{
  "openapi": "3.1.0",
  "info": {
    "title": "Docana Platform API",
    "version": "1.0.0",
    "description": "REST API of the Docana platform. Authenticate with a personal API key (`Authorization: ApiKey <key>`) or reuse the browser session cookie. `/api/v1/` is the canonical, versioned surface. The same operations also answer on the versionless `/api/` paths, which exist as permanent aliases. All paths use a trailing slash: requests without one are redirected with a 308, which drops the body of POST requests in most HTTP clients."
  },
  "servers": [
    {
      "url": "https://platform.docana.com",
      "description": "Production"
    }
  ],
  "security": [
    {
      "apiKey": []
    },
    {
      "sessionCookie": []
    }
  ],
  "tags": [
    {
      "name": "agent-analytics",
      "x-displayName": "Agent Analytics",
      "description": "Usage, evaluation, and conversation analytics for an agent."
    },
    {
      "name": "agent-executions",
      "x-displayName": "Agent Executions",
      "description": "Inspect and stop individual agent executions."
    },
    {
      "name": "agent-improvement",
      "x-displayName": "Agent Improvement",
      "description": "Auto-improve runs that iterate on an agent flow toward a target score."
    },
    {
      "name": "agent-routines",
      "x-displayName": "Agent Routines",
      "description": "Scheduled and event-triggered routines that run an agent on their own."
    },
    {
      "name": "agent-testing",
      "x-displayName": "Agent Testing",
      "description": "Test cases and test runs that check an agent against expected behavior."
    },
    {
      "name": "agents",
      "x-displayName": "Agents",
      "description": "Create, validate, import, export, publish, and execute agents."
    },
    {
      "name": "ai-tools",
      "x-displayName": "AI Tools",
      "description": "Built-in tool definitions agents can use."
    },
    {
      "name": "applications",
      "x-displayName": "Applications",
      "description": "Applications, their environments, allowed websites, and recommendations."
    },
    {
      "name": "artifacts",
      "x-displayName": "Artifacts",
      "description": "Documents generated in conversations, saved as versioned artifacts."
    },
    {
      "name": "assistant",
      "x-displayName": "Assistant",
      "description": "Helpers for the platform assistant, such as attachment validation."
    },
    {
      "name": "document-templates",
      "x-displayName": "Document Templates",
      "description": "Import and export document template bundles."
    },
    {
      "name": "evaluation-criteria",
      "x-displayName": "Evaluation Criteria",
      "description": "Criteria used to score agent answers."
    },
    {
      "name": "integrations",
      "x-displayName": "Integrations",
      "description": "Third-party integrations connected to the workspace."
    },
    {
      "name": "knowledge",
      "x-displayName": "Knowledge",
      "description": "Libraries, collections, and documents that make up the knowledge base."
    },
    {
      "name": "mcp-servers",
      "x-displayName": "MCP Servers",
      "description": "MCP server connections and their OAuth lifecycle."
    },
    {
      "name": "messages",
      "x-displayName": "Messages",
      "description": "Individual messages within conversation threads."
    },
    {
      "name": "search",
      "x-displayName": "Search",
      "description": "Semantic and quick search over the knowledge base."
    },
    {
      "name": "skills",
      "x-displayName": "Skills",
      "description": "Reusable skills, uploaded as packages or installed from the registry."
    },
    {
      "name": "threads",
      "x-displayName": "Threads",
      "description": "Conversation threads, their messages, and archive lifecycle."
    },
    {
      "name": "usage",
      "x-displayName": "Usage",
      "description": "Workspace usage reporting."
    },
    {
      "name": "users",
      "x-displayName": "Users",
      "description": "The authenticated user and user metadata."
    }
  ],
  "components": {
    "schemas": {
      "Error": {
        "type": "object",
        "description": "Error envelope returned by every non-2xx response.",
        "properties": {
          "error": {
            "type": "string",
            "description": "Human-readable message stating what went wrong."
          },
          "code": {
            "type": "string",
            "description": "Machine-readable error code, present on errors raised before routing (e.g. `auth/credentials-missing`, `api/versionless-retired`, `api/unknown-path`, `rate-limit/exceeded`)."
          },
          "details": {
            "description": "Extra context some errors attach, e.g. the offending field or id."
          },
          "validationErrors": {
            "type": "object",
            "description": "Flattened Zod issues, present only on request validation failures."
          }
        },
        "required": [
          "error"
        ]
      },
      "createAgent_schema0": {
        "anyOf": [
          {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "source": {
                    "description": "The data source to evaluate the condition against.",
                    "type": "string",
                    "enum": [
                      "evaluation",
                      "vars",
                      "context",
                      "input",
                      "node",
                      "state"
                    ]
                  },
                  "of": {
                    "description": "Target node identifier when source is \"node\".",
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "nodeId": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "nodeId"
                        ]
                      }
                    ]
                  },
                  "path": {
                    "description": "The property path within the source to evaluate. Common paths when source is \"evaluation\": \"scores.mean\" (average score 0-10), \"structuredData.<field>\" (a typed field declared via structuredDataParams on a criterion of this node), \"results[<i>].score\" (one criterion's score). When source is \"node\", prefix with \"evaluation.\": e.g. \"evaluation.structuredData.<field>\". A \"[*]\" segment projects the rest of the path over a list, so a field inside a list of objects can be compared with the ordinary operators: \"webhookResponse.body.data.documents[*].status\" resolves to every document's status, which \"contains\" then judges by value. Without it those operators see whole objects and never match. Items lacking the field are omitted, so \"length\" counts values rather than list positions.",
                    "type": "string"
                  },
                  "valueType": {
                    "description": "How the visual editor should present this field. Display only — the executor ignores it and infers types from the runtime value. It is stored because the shape of `value` cannot always reveal the intent: a \"length\" comparison looks identical whether it counts characters or list items, and a unary operator such as \"isNull\" stores no value at all. Without it the editor would silently redisplay an \"array\" or \"object\" field as \"string\".",
                    "type": "string",
                    "enum": [
                      "string",
                      "number",
                      "boolean",
                      "array",
                      "object"
                    ]
                  },
                  "op": {
                    "description": "The comparison operator to apply.",
                    "type": "string",
                    "enum": [
                      "eq",
                      "neq",
                      "gt",
                      "gte",
                      "lt",
                      "lte",
                      "in",
                      "notIn",
                      "contains",
                      "exists",
                      "notExists",
                      "isEmpty",
                      "isNotEmpty",
                      "isNull",
                      "isNotNull",
                      "regex"
                    ]
                  },
                  "value": {
                    "description": "The value to compare against. Optional for unary operators like exists."
                  }
                },
                "required": [
                  "source",
                  "path",
                  "op"
                ]
              },
              {
                "type": "object",
                "properties": {
                  "source": {
                    "description": "The data source to evaluate the condition against.",
                    "type": "string",
                    "enum": [
                      "evaluation",
                      "vars",
                      "context",
                      "input",
                      "node",
                      "state"
                    ]
                  },
                  "of": {
                    "description": "Target node identifier when source is \"node\".",
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "nodeId": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "nodeId"
                        ]
                      }
                    ]
                  },
                  "path": {
                    "description": "The property path within the source to evaluate. Common paths when source is \"evaluation\": \"scores.mean\" (average score 0-10), \"structuredData.<field>\" (a typed field declared via structuredDataParams on a criterion of this node), \"results[<i>].score\" (one criterion's score). When source is \"node\", prefix with \"evaluation.\": e.g. \"evaluation.structuredData.<field>\". A \"[*]\" segment projects the rest of the path over a list, so a field inside a list of objects can be compared with the ordinary operators: \"webhookResponse.body.data.documents[*].status\" resolves to every document's status, which \"contains\" then judges by value. Without it those operators see whole objects and never match. Items lacking the field are omitted, so \"length\" counts values rather than list positions.",
                    "type": "string"
                  },
                  "valueType": {
                    "description": "How the visual editor should present this field. Display only — the executor ignores it and infers types from the runtime value. It is stored because the shape of `value` cannot always reveal the intent: a \"length\" comparison looks identical whether it counts characters or list items, and a unary operator such as \"isNull\" stores no value at all. Without it the editor would silently redisplay an \"array\" or \"object\" field as \"string\".",
                    "type": "string",
                    "enum": [
                      "string",
                      "number",
                      "boolean",
                      "array",
                      "object"
                    ]
                  },
                  "op": {
                    "description": "The length comparison operator to apply.",
                    "type": "string",
                    "const": "length"
                  },
                  "value": {
                    "description": "The length comparator and finite number to compare against.",
                    "type": "object",
                    "properties": {
                      "comparator": {
                        "type": "string",
                        "enum": [
                          "eq",
                          "gt",
                          "gte",
                          "lt",
                          "lte"
                        ]
                      },
                      "value": {
                        "type": "number"
                      }
                    },
                    "required": [
                      "comparator",
                      "value"
                    ]
                  }
                },
                "required": [
                  "source",
                  "path",
                  "op",
                  "value"
                ]
              }
            ]
          },
          {
            "type": "object",
            "properties": {
              "all": {
                "description": "All of the following conditions must be met.",
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/createAgent_schema0"
                }
              },
              "any": {
                "description": "Any of the following conditions must be met.",
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/createAgent_schema0"
                }
              },
              "not": {
                "description": "The following condition must not be met.",
                "$ref": "#/components/schemas/createAgent_schema0"
              }
            },
            "additionalProperties": false
          }
        ]
      },
      "importAgents_schema0": {
        "anyOf": [
          {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "source": {
                    "description": "The data source to evaluate the condition against.",
                    "type": "string",
                    "enum": [
                      "evaluation",
                      "vars",
                      "context",
                      "input",
                      "node",
                      "state"
                    ]
                  },
                  "of": {
                    "description": "Target node identifier when source is \"node\".",
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "nodeId": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "nodeId"
                        ]
                      }
                    ]
                  },
                  "path": {
                    "description": "The property path within the source to evaluate. Common paths when source is \"evaluation\": \"scores.mean\" (average score 0-10), \"structuredData.<field>\" (a typed field declared via structuredDataParams on a criterion of this node), \"results[<i>].score\" (one criterion's score). When source is \"node\", prefix with \"evaluation.\": e.g. \"evaluation.structuredData.<field>\". A \"[*]\" segment projects the rest of the path over a list, so a field inside a list of objects can be compared with the ordinary operators: \"webhookResponse.body.data.documents[*].status\" resolves to every document's status, which \"contains\" then judges by value. Without it those operators see whole objects and never match. Items lacking the field are omitted, so \"length\" counts values rather than list positions.",
                    "type": "string"
                  },
                  "valueType": {
                    "description": "How the visual editor should present this field. Display only — the executor ignores it and infers types from the runtime value. It is stored because the shape of `value` cannot always reveal the intent: a \"length\" comparison looks identical whether it counts characters or list items, and a unary operator such as \"isNull\" stores no value at all. Without it the editor would silently redisplay an \"array\" or \"object\" field as \"string\".",
                    "type": "string",
                    "enum": [
                      "string",
                      "number",
                      "boolean",
                      "array",
                      "object"
                    ]
                  },
                  "op": {
                    "description": "The comparison operator to apply.",
                    "type": "string",
                    "enum": [
                      "eq",
                      "neq",
                      "gt",
                      "gte",
                      "lt",
                      "lte",
                      "in",
                      "notIn",
                      "contains",
                      "exists",
                      "notExists",
                      "isEmpty",
                      "isNotEmpty",
                      "isNull",
                      "isNotNull",
                      "regex"
                    ]
                  },
                  "value": {
                    "description": "The value to compare against. Optional for unary operators like exists."
                  }
                },
                "required": [
                  "source",
                  "path",
                  "op"
                ]
              },
              {
                "type": "object",
                "properties": {
                  "source": {
                    "description": "The data source to evaluate the condition against.",
                    "type": "string",
                    "enum": [
                      "evaluation",
                      "vars",
                      "context",
                      "input",
                      "node",
                      "state"
                    ]
                  },
                  "of": {
                    "description": "Target node identifier when source is \"node\".",
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "nodeId": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "nodeId"
                        ]
                      }
                    ]
                  },
                  "path": {
                    "description": "The property path within the source to evaluate. Common paths when source is \"evaluation\": \"scores.mean\" (average score 0-10), \"structuredData.<field>\" (a typed field declared via structuredDataParams on a criterion of this node), \"results[<i>].score\" (one criterion's score). When source is \"node\", prefix with \"evaluation.\": e.g. \"evaluation.structuredData.<field>\". A \"[*]\" segment projects the rest of the path over a list, so a field inside a list of objects can be compared with the ordinary operators: \"webhookResponse.body.data.documents[*].status\" resolves to every document's status, which \"contains\" then judges by value. Without it those operators see whole objects and never match. Items lacking the field are omitted, so \"length\" counts values rather than list positions.",
                    "type": "string"
                  },
                  "valueType": {
                    "description": "How the visual editor should present this field. Display only — the executor ignores it and infers types from the runtime value. It is stored because the shape of `value` cannot always reveal the intent: a \"length\" comparison looks identical whether it counts characters or list items, and a unary operator such as \"isNull\" stores no value at all. Without it the editor would silently redisplay an \"array\" or \"object\" field as \"string\".",
                    "type": "string",
                    "enum": [
                      "string",
                      "number",
                      "boolean",
                      "array",
                      "object"
                    ]
                  },
                  "op": {
                    "description": "The length comparison operator to apply.",
                    "type": "string",
                    "const": "length"
                  },
                  "value": {
                    "description": "The length comparator and finite number to compare against.",
                    "type": "object",
                    "properties": {
                      "comparator": {
                        "type": "string",
                        "enum": [
                          "eq",
                          "gt",
                          "gte",
                          "lt",
                          "lte"
                        ]
                      },
                      "value": {
                        "type": "number"
                      }
                    },
                    "required": [
                      "comparator",
                      "value"
                    ]
                  }
                },
                "required": [
                  "source",
                  "path",
                  "op",
                  "value"
                ]
              }
            ]
          },
          {
            "type": "object",
            "properties": {
              "all": {
                "description": "All of the following conditions must be met.",
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/importAgents_schema0"
                }
              },
              "any": {
                "description": "Any of the following conditions must be met.",
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/importAgents_schema0"
                }
              },
              "not": {
                "description": "The following condition must not be met.",
                "$ref": "#/components/schemas/importAgents_schema0"
              }
            },
            "additionalProperties": false
          }
        ]
      },
      "importAgents_schema1": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "number"
          },
          {
            "type": "boolean"
          },
          {
            "type": "null"
          },
          {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/importAgents_schema1"
            }
          },
          {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "$ref": "#/components/schemas/importAgents_schema1"
            }
          }
        ]
      },
      "checkAgentImport_schema0": {
        "anyOf": [
          {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "source": {
                    "description": "The data source to evaluate the condition against.",
                    "type": "string",
                    "enum": [
                      "evaluation",
                      "vars",
                      "context",
                      "input",
                      "node",
                      "state"
                    ]
                  },
                  "of": {
                    "description": "Target node identifier when source is \"node\".",
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "nodeId": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "nodeId"
                        ]
                      }
                    ]
                  },
                  "path": {
                    "description": "The property path within the source to evaluate. Common paths when source is \"evaluation\": \"scores.mean\" (average score 0-10), \"structuredData.<field>\" (a typed field declared via structuredDataParams on a criterion of this node), \"results[<i>].score\" (one criterion's score). When source is \"node\", prefix with \"evaluation.\": e.g. \"evaluation.structuredData.<field>\". A \"[*]\" segment projects the rest of the path over a list, so a field inside a list of objects can be compared with the ordinary operators: \"webhookResponse.body.data.documents[*].status\" resolves to every document's status, which \"contains\" then judges by value. Without it those operators see whole objects and never match. Items lacking the field are omitted, so \"length\" counts values rather than list positions.",
                    "type": "string"
                  },
                  "valueType": {
                    "description": "How the visual editor should present this field. Display only — the executor ignores it and infers types from the runtime value. It is stored because the shape of `value` cannot always reveal the intent: a \"length\" comparison looks identical whether it counts characters or list items, and a unary operator such as \"isNull\" stores no value at all. Without it the editor would silently redisplay an \"array\" or \"object\" field as \"string\".",
                    "type": "string",
                    "enum": [
                      "string",
                      "number",
                      "boolean",
                      "array",
                      "object"
                    ]
                  },
                  "op": {
                    "description": "The comparison operator to apply.",
                    "type": "string",
                    "enum": [
                      "eq",
                      "neq",
                      "gt",
                      "gte",
                      "lt",
                      "lte",
                      "in",
                      "notIn",
                      "contains",
                      "exists",
                      "notExists",
                      "isEmpty",
                      "isNotEmpty",
                      "isNull",
                      "isNotNull",
                      "regex"
                    ]
                  },
                  "value": {
                    "description": "The value to compare against. Optional for unary operators like exists."
                  }
                },
                "required": [
                  "source",
                  "path",
                  "op"
                ]
              },
              {
                "type": "object",
                "properties": {
                  "source": {
                    "description": "The data source to evaluate the condition against.",
                    "type": "string",
                    "enum": [
                      "evaluation",
                      "vars",
                      "context",
                      "input",
                      "node",
                      "state"
                    ]
                  },
                  "of": {
                    "description": "Target node identifier when source is \"node\".",
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "nodeId": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "nodeId"
                        ]
                      }
                    ]
                  },
                  "path": {
                    "description": "The property path within the source to evaluate. Common paths when source is \"evaluation\": \"scores.mean\" (average score 0-10), \"structuredData.<field>\" (a typed field declared via structuredDataParams on a criterion of this node), \"results[<i>].score\" (one criterion's score). When source is \"node\", prefix with \"evaluation.\": e.g. \"evaluation.structuredData.<field>\". A \"[*]\" segment projects the rest of the path over a list, so a field inside a list of objects can be compared with the ordinary operators: \"webhookResponse.body.data.documents[*].status\" resolves to every document's status, which \"contains\" then judges by value. Without it those operators see whole objects and never match. Items lacking the field are omitted, so \"length\" counts values rather than list positions.",
                    "type": "string"
                  },
                  "valueType": {
                    "description": "How the visual editor should present this field. Display only — the executor ignores it and infers types from the runtime value. It is stored because the shape of `value` cannot always reveal the intent: a \"length\" comparison looks identical whether it counts characters or list items, and a unary operator such as \"isNull\" stores no value at all. Without it the editor would silently redisplay an \"array\" or \"object\" field as \"string\".",
                    "type": "string",
                    "enum": [
                      "string",
                      "number",
                      "boolean",
                      "array",
                      "object"
                    ]
                  },
                  "op": {
                    "description": "The length comparison operator to apply.",
                    "type": "string",
                    "const": "length"
                  },
                  "value": {
                    "description": "The length comparator and finite number to compare against.",
                    "type": "object",
                    "properties": {
                      "comparator": {
                        "type": "string",
                        "enum": [
                          "eq",
                          "gt",
                          "gte",
                          "lt",
                          "lte"
                        ]
                      },
                      "value": {
                        "type": "number"
                      }
                    },
                    "required": [
                      "comparator",
                      "value"
                    ]
                  }
                },
                "required": [
                  "source",
                  "path",
                  "op",
                  "value"
                ]
              }
            ]
          },
          {
            "type": "object",
            "properties": {
              "all": {
                "description": "All of the following conditions must be met.",
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/checkAgentImport_schema0"
                }
              },
              "any": {
                "description": "Any of the following conditions must be met.",
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/checkAgentImport_schema0"
                }
              },
              "not": {
                "description": "The following condition must not be met.",
                "$ref": "#/components/schemas/checkAgentImport_schema0"
              }
            },
            "additionalProperties": false
          }
        ]
      },
      "checkAgentImport_schema1": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "number"
          },
          {
            "type": "boolean"
          },
          {
            "type": "null"
          },
          {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/checkAgentImport_schema1"
            }
          },
          {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "$ref": "#/components/schemas/checkAgentImport_schema1"
            }
          }
        ]
      },
      "validateAgentSpec_schema0": {
        "anyOf": [
          {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "source": {
                    "description": "The data source to evaluate the condition against.",
                    "type": "string",
                    "enum": [
                      "evaluation",
                      "vars",
                      "context",
                      "input",
                      "node",
                      "state"
                    ]
                  },
                  "of": {
                    "description": "Target node identifier when source is \"node\".",
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "nodeId": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "nodeId"
                        ]
                      }
                    ]
                  },
                  "path": {
                    "description": "The property path within the source to evaluate. Common paths when source is \"evaluation\": \"scores.mean\" (average score 0-10), \"structuredData.<field>\" (a typed field declared via structuredDataParams on a criterion of this node), \"results[<i>].score\" (one criterion's score). When source is \"node\", prefix with \"evaluation.\": e.g. \"evaluation.structuredData.<field>\". A \"[*]\" segment projects the rest of the path over a list, so a field inside a list of objects can be compared with the ordinary operators: \"webhookResponse.body.data.documents[*].status\" resolves to every document's status, which \"contains\" then judges by value. Without it those operators see whole objects and never match. Items lacking the field are omitted, so \"length\" counts values rather than list positions.",
                    "type": "string"
                  },
                  "valueType": {
                    "description": "How the visual editor should present this field. Display only — the executor ignores it and infers types from the runtime value. It is stored because the shape of `value` cannot always reveal the intent: a \"length\" comparison looks identical whether it counts characters or list items, and a unary operator such as \"isNull\" stores no value at all. Without it the editor would silently redisplay an \"array\" or \"object\" field as \"string\".",
                    "type": "string",
                    "enum": [
                      "string",
                      "number",
                      "boolean",
                      "array",
                      "object"
                    ]
                  },
                  "op": {
                    "description": "The comparison operator to apply.",
                    "type": "string",
                    "enum": [
                      "eq",
                      "neq",
                      "gt",
                      "gte",
                      "lt",
                      "lte",
                      "in",
                      "notIn",
                      "contains",
                      "exists",
                      "notExists",
                      "isEmpty",
                      "isNotEmpty",
                      "isNull",
                      "isNotNull",
                      "regex"
                    ]
                  },
                  "value": {
                    "description": "The value to compare against. Optional for unary operators like exists."
                  }
                },
                "required": [
                  "source",
                  "path",
                  "op"
                ]
              },
              {
                "type": "object",
                "properties": {
                  "source": {
                    "description": "The data source to evaluate the condition against.",
                    "type": "string",
                    "enum": [
                      "evaluation",
                      "vars",
                      "context",
                      "input",
                      "node",
                      "state"
                    ]
                  },
                  "of": {
                    "description": "Target node identifier when source is \"node\".",
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "nodeId": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "nodeId"
                        ]
                      }
                    ]
                  },
                  "path": {
                    "description": "The property path within the source to evaluate. Common paths when source is \"evaluation\": \"scores.mean\" (average score 0-10), \"structuredData.<field>\" (a typed field declared via structuredDataParams on a criterion of this node), \"results[<i>].score\" (one criterion's score). When source is \"node\", prefix with \"evaluation.\": e.g. \"evaluation.structuredData.<field>\". A \"[*]\" segment projects the rest of the path over a list, so a field inside a list of objects can be compared with the ordinary operators: \"webhookResponse.body.data.documents[*].status\" resolves to every document's status, which \"contains\" then judges by value. Without it those operators see whole objects and never match. Items lacking the field are omitted, so \"length\" counts values rather than list positions.",
                    "type": "string"
                  },
                  "valueType": {
                    "description": "How the visual editor should present this field. Display only — the executor ignores it and infers types from the runtime value. It is stored because the shape of `value` cannot always reveal the intent: a \"length\" comparison looks identical whether it counts characters or list items, and a unary operator such as \"isNull\" stores no value at all. Without it the editor would silently redisplay an \"array\" or \"object\" field as \"string\".",
                    "type": "string",
                    "enum": [
                      "string",
                      "number",
                      "boolean",
                      "array",
                      "object"
                    ]
                  },
                  "op": {
                    "description": "The length comparison operator to apply.",
                    "type": "string",
                    "const": "length"
                  },
                  "value": {
                    "description": "The length comparator and finite number to compare against.",
                    "type": "object",
                    "properties": {
                      "comparator": {
                        "type": "string",
                        "enum": [
                          "eq",
                          "gt",
                          "gte",
                          "lt",
                          "lte"
                        ]
                      },
                      "value": {
                        "type": "number"
                      }
                    },
                    "required": [
                      "comparator",
                      "value"
                    ]
                  }
                },
                "required": [
                  "source",
                  "path",
                  "op",
                  "value"
                ]
              }
            ]
          },
          {
            "type": "object",
            "properties": {
              "all": {
                "description": "All of the following conditions must be met.",
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/validateAgentSpec_schema0"
                }
              },
              "any": {
                "description": "Any of the following conditions must be met.",
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/validateAgentSpec_schema0"
                }
              },
              "not": {
                "description": "The following condition must not be met.",
                "$ref": "#/components/schemas/validateAgentSpec_schema0"
              }
            },
            "additionalProperties": false
          }
        ]
      },
      "updateAgentSpec_schema0": {
        "anyOf": [
          {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "source": {
                    "description": "The data source to evaluate the condition against.",
                    "type": "string",
                    "enum": [
                      "evaluation",
                      "vars",
                      "context",
                      "input",
                      "node",
                      "state"
                    ]
                  },
                  "of": {
                    "description": "Target node identifier when source is \"node\".",
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "nodeId": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "nodeId"
                        ]
                      }
                    ]
                  },
                  "path": {
                    "description": "The property path within the source to evaluate. Common paths when source is \"evaluation\": \"scores.mean\" (average score 0-10), \"structuredData.<field>\" (a typed field declared via structuredDataParams on a criterion of this node), \"results[<i>].score\" (one criterion's score). When source is \"node\", prefix with \"evaluation.\": e.g. \"evaluation.structuredData.<field>\". A \"[*]\" segment projects the rest of the path over a list, so a field inside a list of objects can be compared with the ordinary operators: \"webhookResponse.body.data.documents[*].status\" resolves to every document's status, which \"contains\" then judges by value. Without it those operators see whole objects and never match. Items lacking the field are omitted, so \"length\" counts values rather than list positions.",
                    "type": "string"
                  },
                  "valueType": {
                    "description": "How the visual editor should present this field. Display only — the executor ignores it and infers types from the runtime value. It is stored because the shape of `value` cannot always reveal the intent: a \"length\" comparison looks identical whether it counts characters or list items, and a unary operator such as \"isNull\" stores no value at all. Without it the editor would silently redisplay an \"array\" or \"object\" field as \"string\".",
                    "type": "string",
                    "enum": [
                      "string",
                      "number",
                      "boolean",
                      "array",
                      "object"
                    ]
                  },
                  "op": {
                    "description": "The comparison operator to apply.",
                    "type": "string",
                    "enum": [
                      "eq",
                      "neq",
                      "gt",
                      "gte",
                      "lt",
                      "lte",
                      "in",
                      "notIn",
                      "contains",
                      "exists",
                      "notExists",
                      "isEmpty",
                      "isNotEmpty",
                      "isNull",
                      "isNotNull",
                      "regex"
                    ]
                  },
                  "value": {
                    "description": "The value to compare against. Optional for unary operators like exists."
                  }
                },
                "required": [
                  "source",
                  "path",
                  "op"
                ]
              },
              {
                "type": "object",
                "properties": {
                  "source": {
                    "description": "The data source to evaluate the condition against.",
                    "type": "string",
                    "enum": [
                      "evaluation",
                      "vars",
                      "context",
                      "input",
                      "node",
                      "state"
                    ]
                  },
                  "of": {
                    "description": "Target node identifier when source is \"node\".",
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "nodeId": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "nodeId"
                        ]
                      }
                    ]
                  },
                  "path": {
                    "description": "The property path within the source to evaluate. Common paths when source is \"evaluation\": \"scores.mean\" (average score 0-10), \"structuredData.<field>\" (a typed field declared via structuredDataParams on a criterion of this node), \"results[<i>].score\" (one criterion's score). When source is \"node\", prefix with \"evaluation.\": e.g. \"evaluation.structuredData.<field>\". A \"[*]\" segment projects the rest of the path over a list, so a field inside a list of objects can be compared with the ordinary operators: \"webhookResponse.body.data.documents[*].status\" resolves to every document's status, which \"contains\" then judges by value. Without it those operators see whole objects and never match. Items lacking the field are omitted, so \"length\" counts values rather than list positions.",
                    "type": "string"
                  },
                  "valueType": {
                    "description": "How the visual editor should present this field. Display only — the executor ignores it and infers types from the runtime value. It is stored because the shape of `value` cannot always reveal the intent: a \"length\" comparison looks identical whether it counts characters or list items, and a unary operator such as \"isNull\" stores no value at all. Without it the editor would silently redisplay an \"array\" or \"object\" field as \"string\".",
                    "type": "string",
                    "enum": [
                      "string",
                      "number",
                      "boolean",
                      "array",
                      "object"
                    ]
                  },
                  "op": {
                    "description": "The length comparison operator to apply.",
                    "type": "string",
                    "const": "length"
                  },
                  "value": {
                    "description": "The length comparator and finite number to compare against.",
                    "type": "object",
                    "properties": {
                      "comparator": {
                        "type": "string",
                        "enum": [
                          "eq",
                          "gt",
                          "gte",
                          "lt",
                          "lte"
                        ]
                      },
                      "value": {
                        "type": "number"
                      }
                    },
                    "required": [
                      "comparator",
                      "value"
                    ]
                  }
                },
                "required": [
                  "source",
                  "path",
                  "op",
                  "value"
                ]
              }
            ]
          },
          {
            "type": "object",
            "properties": {
              "all": {
                "description": "All of the following conditions must be met.",
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/updateAgentSpec_schema0"
                }
              },
              "any": {
                "description": "Any of the following conditions must be met.",
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/updateAgentSpec_schema0"
                }
              },
              "not": {
                "description": "The following condition must not be met.",
                "$ref": "#/components/schemas/updateAgentSpec_schema0"
              }
            },
            "additionalProperties": false
          }
        ]
      },
      "exportAgent_schema0": {
        "anyOf": [
          {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "source": {
                    "description": "The data source to evaluate the condition against.",
                    "type": "string",
                    "enum": [
                      "evaluation",
                      "vars",
                      "context",
                      "input",
                      "node",
                      "state"
                    ]
                  },
                  "of": {
                    "description": "Target node identifier when source is \"node\".",
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "nodeId": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "nodeId"
                        ],
                        "additionalProperties": false
                      }
                    ]
                  },
                  "path": {
                    "description": "The property path within the source to evaluate. Common paths when source is \"evaluation\": \"scores.mean\" (average score 0-10), \"structuredData.<field>\" (a typed field declared via structuredDataParams on a criterion of this node), \"results[<i>].score\" (one criterion's score). When source is \"node\", prefix with \"evaluation.\": e.g. \"evaluation.structuredData.<field>\". A \"[*]\" segment projects the rest of the path over a list, so a field inside a list of objects can be compared with the ordinary operators: \"webhookResponse.body.data.documents[*].status\" resolves to every document's status, which \"contains\" then judges by value. Without it those operators see whole objects and never match. Items lacking the field are omitted, so \"length\" counts values rather than list positions.",
                    "type": "string"
                  },
                  "valueType": {
                    "description": "How the visual editor should present this field. Display only — the executor ignores it and infers types from the runtime value. It is stored because the shape of `value` cannot always reveal the intent: a \"length\" comparison looks identical whether it counts characters or list items, and a unary operator such as \"isNull\" stores no value at all. Without it the editor would silently redisplay an \"array\" or \"object\" field as \"string\".",
                    "type": "string",
                    "enum": [
                      "string",
                      "number",
                      "boolean",
                      "array",
                      "object"
                    ]
                  },
                  "op": {
                    "description": "The comparison operator to apply.",
                    "type": "string",
                    "enum": [
                      "eq",
                      "neq",
                      "gt",
                      "gte",
                      "lt",
                      "lte",
                      "in",
                      "notIn",
                      "contains",
                      "exists",
                      "notExists",
                      "isEmpty",
                      "isNotEmpty",
                      "isNull",
                      "isNotNull",
                      "regex"
                    ]
                  },
                  "value": {
                    "description": "The value to compare against. Optional for unary operators like exists."
                  }
                },
                "required": [
                  "source",
                  "path",
                  "op"
                ],
                "additionalProperties": false
              },
              {
                "type": "object",
                "properties": {
                  "source": {
                    "description": "The data source to evaluate the condition against.",
                    "type": "string",
                    "enum": [
                      "evaluation",
                      "vars",
                      "context",
                      "input",
                      "node",
                      "state"
                    ]
                  },
                  "of": {
                    "description": "Target node identifier when source is \"node\".",
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "nodeId": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "nodeId"
                        ],
                        "additionalProperties": false
                      }
                    ]
                  },
                  "path": {
                    "description": "The property path within the source to evaluate. Common paths when source is \"evaluation\": \"scores.mean\" (average score 0-10), \"structuredData.<field>\" (a typed field declared via structuredDataParams on a criterion of this node), \"results[<i>].score\" (one criterion's score). When source is \"node\", prefix with \"evaluation.\": e.g. \"evaluation.structuredData.<field>\". A \"[*]\" segment projects the rest of the path over a list, so a field inside a list of objects can be compared with the ordinary operators: \"webhookResponse.body.data.documents[*].status\" resolves to every document's status, which \"contains\" then judges by value. Without it those operators see whole objects and never match. Items lacking the field are omitted, so \"length\" counts values rather than list positions.",
                    "type": "string"
                  },
                  "valueType": {
                    "description": "How the visual editor should present this field. Display only — the executor ignores it and infers types from the runtime value. It is stored because the shape of `value` cannot always reveal the intent: a \"length\" comparison looks identical whether it counts characters or list items, and a unary operator such as \"isNull\" stores no value at all. Without it the editor would silently redisplay an \"array\" or \"object\" field as \"string\".",
                    "type": "string",
                    "enum": [
                      "string",
                      "number",
                      "boolean",
                      "array",
                      "object"
                    ]
                  },
                  "op": {
                    "description": "The length comparison operator to apply.",
                    "type": "string",
                    "const": "length"
                  },
                  "value": {
                    "description": "The length comparator and finite number to compare against.",
                    "type": "object",
                    "properties": {
                      "comparator": {
                        "type": "string",
                        "enum": [
                          "eq",
                          "gt",
                          "gte",
                          "lt",
                          "lte"
                        ]
                      },
                      "value": {
                        "type": "number"
                      }
                    },
                    "required": [
                      "comparator",
                      "value"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "source",
                  "path",
                  "op",
                  "value"
                ],
                "additionalProperties": false
              }
            ]
          },
          {
            "type": "object",
            "properties": {
              "all": {
                "description": "All of the following conditions must be met.",
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/exportAgent_schema0"
                }
              },
              "any": {
                "description": "Any of the following conditions must be met.",
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/exportAgent_schema0"
                }
              },
              "not": {
                "description": "The following condition must not be met.",
                "$ref": "#/components/schemas/exportAgent_schema0"
              }
            },
            "additionalProperties": false
          }
        ]
      },
      "createAgentTestCase_schema0": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "number"
          },
          {
            "type": "boolean"
          },
          {
            "type": "null"
          },
          {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/createAgentTestCase_schema0"
            }
          },
          {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "$ref": "#/components/schemas/createAgentTestCase_schema0"
            }
          }
        ]
      },
      "updateAgentTestCase_schema0": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "number"
          },
          {
            "type": "boolean"
          },
          {
            "type": "null"
          },
          {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/updateAgentTestCase_schema0"
            }
          },
          {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "$ref": "#/components/schemas/updateAgentTestCase_schema0"
            }
          }
        ]
      },
      "getAgentEvalMockBaseline_schema0": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "number"
          },
          {
            "type": "boolean"
          },
          {
            "type": "null"
          },
          {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/getAgentEvalMockBaseline_schema0"
            }
          },
          {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "$ref": "#/components/schemas/getAgentEvalMockBaseline_schema0"
            }
          }
        ]
      },
      "upsertAgentEvalMockBaseline_schema0": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "number"
          },
          {
            "type": "boolean"
          },
          {
            "type": "null"
          },
          {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/upsertAgentEvalMockBaseline_schema0"
            }
          },
          {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "$ref": "#/components/schemas/upsertAgentEvalMockBaseline_schema0"
            }
          }
        ]
      },
      "upsertAgentEvalMockBaseline_schema0_2": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "number"
          },
          {
            "type": "boolean"
          },
          {
            "type": "null"
          },
          {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/upsertAgentEvalMockBaseline_schema0_2"
            }
          },
          {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "$ref": "#/components/schemas/upsertAgentEvalMockBaseline_schema0_2"
            }
          }
        ]
      }
    },
    "securitySchemes": {
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "Authorization",
        "description": "Personal API key, sent as `Authorization: ApiKey <key>`. Keys are created self-serve in the platform settings with one of three scopes (see `x-key-scopes`). Scope-restricted operations reject a key outside their scope with 403.",
        "x-key-scopes": {
          "FULL": "Full access to every documented operation. The default scope.",
          "WIDGET": "Restricted to the operations the embeddable web widget needs.",
          "ROUTINE": "Restricted to triggering agent routines (`POST /api/v1/agents/{agentId}/routines/{routineId}/run/`)."
        }
      },
      "sessionCookie": {
        "type": "apiKey",
        "in": "cookie",
        "name": "SID",
        "description": "Browser session cookie set by the platform login."
      }
    }
  },
  "paths": {
    "/api/v1/agents/": {
      "get": {
        "operationId": "listAgents",
        "summary": "List agents",
        "tags": [
          "agents"
        ],
        "description": "Returns the agents visible to the caller, filtered by `type` (default `CUSTOM`). With `applicationId` it returns the agents of that application, without it only company-scoped agents (agents that belong to no application) are returned. Disabled agents are excluded unless `includeDisabled=true`.",
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Only return agents of this type. `CUSTOM` is a user-built workflow agent. `DOCUMENT_INSIGHTS` and `QUESTION_ANSWERING` are the platform-managed agents behind document insights and question answering.",
            "schema": {
              "examples": [
                "CUSTOM"
              ],
              "default": "CUSTOM",
              "type": "string",
              "enum": [
                "DOCUMENT_INSIGHTS",
                "QUESTION_ANSWERING",
                "CUSTOM"
              ]
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application whose agents to return. When omitted, only company-scoped agents (agents without an application) are returned.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "includeDisabled",
            "in": "query",
            "required": false,
            "description": "Pass the literal string `true` to also include disabled agents. Any other value, or omitting the parameter, returns enabled agents only.",
            "schema": {}
          },
          {
            "name": "onlyPublished",
            "in": "query",
            "required": false,
            "description": "Pass the literal string `true` to only return agents that have a published version. Any other value, or omitting the parameter, returns published and unpublished agents alike.",
            "schema": {}
          },
          {
            "name": "responseShape",
            "in": "query",
            "required": false,
            "description": "Opt into a lean, cursor-paginated summary envelope.",
            "schema": {
              "type": "string",
              "const": "summary"
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Case-insensitive substring match on agent name or description.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size when `responseShape=summary`, between 1 and 100. Defaults to 50.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Opaque cursor returned as nextCursor by a previous summary response.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The list of agents; summary mode returns `{ agents, nextCursor }`.",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "description": "The agents visible to the caller that match the query filters.",
                      "type": "array",
                      "items": {
                        "description": "An agent. Additional fields from the underlying agent model may be present.",
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "The agent's unique id.",
                            "examples": [
                              "cmc4v8xq10001l708h2vxk9d3"
                            ],
                            "type": "string"
                          },
                          "name": {
                            "description": "The agent's display name. Null when the agent has no name yet.",
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "type": {
                            "description": "The agent type: `CUSTOM`, `DOCUMENT_INSIGHTS` or `QUESTION_ANSWERING`.",
                            "examples": [
                              "CUSTOM"
                            ],
                            "type": "string",
                            "enum": [
                              "DOCUMENT_INSIGHTS",
                              "QUESTION_ANSWERING",
                              "CUSTOM"
                            ]
                          },
                          "applicationId": {
                            "description": "Id of the application the agent belongs to. Null for company-scoped agents.",
                            "examples": [
                              42
                            ],
                            "anyOf": [
                              {
                                "type": "number"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "type",
                          "applicationId"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    {
                      "type": "object",
                      "properties": {
                        "agents": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "applicationId": {
                                "anyOf": [
                                  {
                                    "type": "number"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "name": {
                                "anyOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "description": {
                                "anyOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "type": {
                                "type": "string",
                                "enum": [
                                  "DOCUMENT_INSIGHTS",
                                  "QUESTION_ANSWERING",
                                  "CUSTOM"
                                ]
                              },
                              "enabled": {
                                "type": "boolean"
                              },
                              "published": {
                                "type": "boolean"
                              },
                              "createdAt": {
                                "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))$"
                              },
                              "updatedAt": {
                                "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))$"
                              }
                            },
                            "required": [
                              "id",
                              "applicationId",
                              "name",
                              "description",
                              "type",
                              "enabled",
                              "published",
                              "createdAt",
                              "updatedAt"
                            ],
                            "additionalProperties": false
                          }
                        },
                        "nextCursor": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "agents",
                        "nextCursor"
                      ],
                      "additionalProperties": false
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createAgent",
        "summary": "Create workflow agent from a complete spec",
        "tags": [
          "agents"
        ],
        "description": "Creates one actual Docana workflow Agent record from a complete AgentSpec V2: create, build, or draft one new agent. Do not use `saveArtifact` or `importAgents` for this. Validate the complete spec first with `validateAgentSpec`; creation never publishes, so call `publishAgent` separately when the draft is ready.",
        "requestBody": {
          "required": true,
          "description": "One new draft agent. `name` is authoritative over `spec.name`.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "applicationId": {
                    "description": "Application that owns the new draft agent.",
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  "name": {
                    "description": "Authoritative display name for the new agent.",
                    "type": "string",
                    "minLength": 1
                  },
                  "description": {
                    "description": "Optional description. Whitespace is trimmed.",
                    "type": "string"
                  },
                  "spec": {
                    "description": "AgentSpec V2 for the new agent. Its `id` must be omitted; the server assigns the agent id.",
                    "type": "object",
                    "properties": {
                      "version": {
                        "description": "Schema version. Must be \"2.0\".",
                        "type": "string",
                        "const": "2.0"
                      },
                      "name": {
                        "description": "Human-readable name of the agent.",
                        "type": "string"
                      },
                      "prompt": {
                        "description": "System instructions for the agent. Can be a single string or an array of strings joined at runtime.",
                        "anyOf": [
                          {
                            "type": "string",
                            "minLength": 1
                          },
                          {
                            "minItems": 1,
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1
                            }
                          }
                        ]
                      },
                      "llm": {
                        "description": "LLM configuration for the router persona. Optional; uses platform defaults when omitted.",
                        "type": "object",
                        "properties": {
                          "provider": {
                            "description": "The LLM provider identifier (e.g., \"google\", \"openai\").",
                            "type": "string"
                          },
                          "model": {
                            "description": "The model name to use (e.g., \"gemini-2.0-flash\").",
                            "type": "string"
                          },
                          "temperature": {
                            "description": "Sampling temperature (0-2). IGNORED on Gemini 3.x models, which Google deprecated this parameter for on 2026-07-21 — it is accepted and silently discarded, so it no longer makes output more deterministic. Still accepted for older models and for backwards compatibility with existing specs.",
                            "type": "number"
                          },
                          "maxOutputTokens": {
                            "description": "Maximum number of tokens the model can generate.",
                            "type": "number"
                          },
                          "toolChoice": {
                            "description": "Controls how the model uses tools: auto (model decides), required (must use a tool), none (no tools).",
                            "type": "string",
                            "enum": [
                              "auto",
                              "required",
                              "none"
                            ]
                          },
                          "jsonMode": {
                            "description": "If true, the model outputs valid JSON.",
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "provider",
                          "model"
                        ]
                      },
                      "inlineEvaluationCriteria": {
                        "description": "Map of criteria ID to its full definition. Decision nodes reference these by key. These are criteria that have not been persisted to the database yet. During sandbox execution, they are loaded into memory. During publish, they are persisted to the database and this field is cleared.",
                        "type": "object",
                        "propertyNames": {
                          "type": "string"
                        },
                        "additionalProperties": {
                          "type": "object",
                          "properties": {
                            "name": {
                              "description": "Human-readable name of this evaluation criteria. MUST be a non-empty short noun phrase (e.g. \"Real-Estate Availability Intent\"). Empty strings are forbidden.",
                              "type": "string"
                            },
                            "type": {
                              "description": "The evaluation criteria type (e.g., CUSTOM, QUALITY_HELPFULNESS).",
                              "type": "string",
                              "enum": [
                                "QUALITY_ENGAGINGNESS",
                                "QUALITY_COHERENCE",
                                "QUALITY_CONSISTENCY",
                                "QUALITY_FLUENCY",
                                "QUALITY_RELEVANCE",
                                "SECURITY_FINANCIAL_DETECTION",
                                "SECURITY_PII_DETECTION",
                                "SECURITY_ANOMALOUS_CONVERSATION",
                                "PERSONALITY_EXTRAVERSION",
                                "PERSONALITY_OPEN_TO_EXPERIENCE",
                                "PERSONALITY_CONSCIENTIOUSNESS",
                                "PERSONALITY_AGREEABLENESS",
                                "PERSONALITY_NEUROTICISM",
                                "PERSONALITY_OTHER",
                                "DOCUMENT_INSIGHTS",
                                "CUSTOM"
                              ]
                            },
                            "evaluationCriteria": {
                              "description": "REQUIRED non-empty instruction the evaluator follows to assess the input. One or two sentences in plain language: what to assess, and (if structuredDataParams is set) how to populate each declared field. Example: \"Decide whether the user is asking about real-estate availability. Set isAvailability to true only when the user is clearly asking whether a property is available; otherwise false.\" Empty strings, null, or omission make the reasoning useless and are forbidden.",
                              "type": "string"
                            },
                            "evaluationSteps": {
                              "description": "Ordered evaluation steps for the criteria.",
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "evaluationParams": {
                              "description": "Parameters used during evaluation (e.g., INPUT, CONTEXT).",
                              "type": "array",
                              "items": {
                                "type": "string",
                                "enum": [
                                  "INPUT",
                                  "ACTUAL_OUTPUT",
                                  "EXPECTED_OUTPUT",
                                  "CONTEXT",
                                  "RETRIEVAL_CONTEXT",
                                  "EXECUTION_CONTEXT"
                                ]
                              }
                            },
                            "structuredDataParams": {
                              "description": "Map of field name to a natural-language description of what to extract. The description should encode both the type and the legal values, e.g. \"true if the user is asking about real-estate availability, false otherwise\" (boolean), \"one of: AVAILABILITY, PRICING, CONTACT, OTHER\" (enum), or \"numeric score 1-5 reflecting urgency\" (number). Each declared field becomes a routing key accessible from transition conditions as \"evaluation.structuredData.<field>\" (and is also flattened into top-level vars for action templates). Prefer this for routing on what the user meant or asked; use scores.mean for confidence/quality routing.",
                              "anyOf": [
                                {
                                  "type": "object",
                                  "propertyNames": {
                                    "type": "string"
                                  },
                                  "additionalProperties": {}
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "metadata": {
                              "description": "Additional metadata for the criteria.",
                              "anyOf": [
                                {
                                  "type": "object",
                                  "propertyNames": {
                                    "type": "string"
                                  },
                                  "additionalProperties": {}
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "enabled": {
                              "description": "Whether this criteria is enabled. Defaults to true.",
                              "type": "boolean"
                            }
                          },
                          "required": [
                            "name",
                            "type",
                            "evaluationCriteria"
                          ]
                        }
                      },
                      "workflow": {
                        "description": "The workflow definition including entry points and execution nodes.",
                        "type": "object",
                        "properties": {
                          "toolName": {
                            "description": "The tool name used to invoke this agent in the workflow.",
                            "type": "string"
                          },
                          "toolDescription": {
                            "description": "A description of what this agent does, shown to the LLM router.",
                            "type": "string"
                          },
                          "executionTimeoutSeconds": {
                            "description": "Wall-clock ceiling for ONE execution of this workflow, in seconds (30-1800). When the deadline passes the run is aborted — in-flight model calls are cancelled, sub-agents included — and the execution finishes with status TIMED_OUT, with the reason recorded on the nodes that were cut. Optional: an agent that declares nothing keeps the platform behavior (no explicit ceiling). Declare it when the agent legitimately runs for minutes (deep research, long tool chains) so a slow run is never mistaken for a hung one, or when it must never occupy a worker past a known bound. The budget is per attempt: a run resumed after a crash starts a fresh timer.",
                            "type": "integer",
                            "minimum": 30,
                            "maximum": 1800
                          },
                          "entryPoints": {
                            "description": "Entry points into the workflow. MUST contain at least one node ID; an empty array makes the workflow non-executable. When you restructure or rename the first node, update this list in the same operation so it points at the new entry node.",
                            "minItems": 1,
                            "type": "array",
                            "items": {
                              "anyOf": [
                                {
                                  "description": "Node ID to use as an unconditional entry point.",
                                  "type": "string"
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "nodeId": {
                                      "description": "The ID of the entry point node.",
                                      "type": "string"
                                    },
                                    "if": {
                                      "description": "Optional condition that must be met for this entry point to activate.",
                                      "$ref": "#/components/schemas/createAgent_schema0"
                                    }
                                  },
                                  "required": [
                                    "nodeId"
                                  ]
                                }
                              ]
                            }
                          },
                          "nodes": {
                            "description": "The workflow nodes: decision, action, subAgent, end, state, hub, jump, clearCache, javascript, or forEach.",
                            "type": "array",
                            "items": {
                              "anyOf": [
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "decision"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this decision node.",
                                      "type": "string"
                                    },
                                    "evaluationCriteria": {
                                      "description": "Evaluation criteria IDs (string references) or inline criteria objects.",
                                      "type": "array",
                                      "items": {
                                        "anyOf": [
                                          {
                                            "type": "string"
                                          },
                                          {
                                            "type": "object",
                                            "properties": {
                                              "id": {
                                                "type": "string"
                                              },
                                              "name": {
                                                "description": "Required non-empty short human-readable name for this criterion (e.g. \"Real-Estate Availability Intent\"). Never an empty string.",
                                                "type": "string"
                                              },
                                              "type": {
                                                "type": "string",
                                                "enum": [
                                                  "QUALITY_ENGAGINGNESS",
                                                  "QUALITY_COHERENCE",
                                                  "QUALITY_CONSISTENCY",
                                                  "QUALITY_FLUENCY",
                                                  "QUALITY_RELEVANCE",
                                                  "SECURITY_FINANCIAL_DETECTION",
                                                  "SECURITY_PII_DETECTION",
                                                  "SECURITY_ANOMALOUS_CONVERSATION",
                                                  "PERSONALITY_EXTRAVERSION",
                                                  "PERSONALITY_OPEN_TO_EXPERIENCE",
                                                  "PERSONALITY_CONSCIENTIOUSNESS",
                                                  "PERSONALITY_AGREEABLENESS",
                                                  "PERSONALITY_NEUROTICISM",
                                                  "PERSONALITY_OTHER",
                                                  "DOCUMENT_INSIGHTS",
                                                  "CUSTOM"
                                                ]
                                              },
                                              "evaluationCriteria": {
                                                "description": "REQUIRED non-empty instruction telling the evaluator what to assess. One or two sentences in plain language: what to evaluate, and — when structuredDataParams is set — how to populate each declared field. Empty strings, null, or omission are forbidden; an empty description leaves the reasoning useless. Example: \"Decide whether the user is asking about real-estate availability. Set isAvailability to true only when the user is clearly asking whether a property is available; otherwise false.\"",
                                                "type": "string"
                                              },
                                              "evaluationSteps": {
                                                "type": "array",
                                                "items": {
                                                  "type": "string"
                                                }
                                              },
                                              "structuredDataParams": {
                                                "anyOf": [
                                                  {
                                                    "type": "object",
                                                    "propertyNames": {
                                                      "type": "string"
                                                    },
                                                    "additionalProperties": {}
                                                  },
                                                  {
                                                    "type": "null"
                                                  }
                                                ]
                                              },
                                              "metadata": {
                                                "anyOf": [
                                                  {
                                                    "type": "object",
                                                    "propertyNames": {
                                                      "type": "string"
                                                    },
                                                    "additionalProperties": {}
                                                  },
                                                  {
                                                    "type": "null"
                                                  }
                                                ]
                                              },
                                              "enabled": {
                                                "type": "boolean"
                                              },
                                              "applicationId": {
                                                "type": "number"
                                              },
                                              "evaluationParams": {
                                                "type": "array",
                                                "items": {
                                                  "type": "string",
                                                  "enum": [
                                                    "INPUT",
                                                    "ACTUAL_OUTPUT",
                                                    "EXPECTED_OUTPUT",
                                                    "CONTEXT",
                                                    "RETRIEVAL_CONTEXT",
                                                    "EXECUTION_CONTEXT"
                                                  ]
                                                }
                                              }
                                            },
                                            "required": [
                                              "name",
                                              "type",
                                              "evaluationCriteria"
                                            ]
                                          }
                                        ]
                                      }
                                    },
                                    "transition": {
                                      "description": "Transitions to other nodes based on evaluation results.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/createAgent_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    },
                                    "cachePolicy": {
                                      "description": "Controls execution caching for this decision node across messages in a conversation. auto (default): cache result and use a lightweight guard evaluation to detect staleness. always: always use cached result until explicitly cleared. never: always re-evaluate all criteria every message (disables caching).",
                                      "type": "string",
                                      "enum": [
                                        "auto",
                                        "always",
                                        "never"
                                      ]
                                    },
                                    "selectionPolicy": {
                                      "description": "Controls which enabled criteria are evaluated each message. all (default): every enabled criterion runs. contextual: a lightweight router selects only the criteria relevant to the current input and conversation state; the rest are skipped. Skipped criteria are not evaluated, so their structuredData fields are absent downstream (route on them with the \"exists\"/\"notExists\" operators) and scores.mean reflects only the criteria that ran.",
                                      "type": "string",
                                      "enum": [
                                        "all",
                                        "contextual"
                                      ]
                                    },
                                    "alwaysRunCriteria": {
                                      "description": "Only used when selectionPolicy is \"contextual\": IDs of evaluation criteria that always run (they bypass the router); every other criterion is AI-selected per message. Use this to pin extractors whose structuredData a downstream node depends on. Ignored when selectionPolicy is \"all\".",
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    },
                                    "contextualSelectionPrompt": {
                                      "description": "Only used when selectionPolicy is \"contextual\": extra author guidance appended to the built-in router prompt to steer which criteria it picks (e.g. \"prefer running Consultar NFSe whenever the user mentions a nota fiscal, even indirectly\"). It augments the router — it does not replace its output contract or the safe fallback of running everything. Ignored when selectionPolicy is \"all\".",
                                      "type": "string"
                                    },
                                    "routingPolicy": {
                                      "description": "How many REASONINGS (criteria) may win the routing on this node per message. all (default): every matching conditional transition fires in parallel. bestReasoning: only the highest-scoring reasoning wins — ALL matched transitions whose condition is anchored on it fire (they are that reasoning's flow), everything anchored on other reasonings is suppressed. topReasonings: like bestReasoning but the best `maxReasonings` reasonings win. A matched transition is anchored on the highest-scoring criterion its condition references (via \"resultsById.<id>.score\" paths, at any nesting). Score ties between reasonings break by position in this node's evaluationCriteria list (earlier wins) — reorder the list to set priority. Matched transitions that reference NO criterion score (pure structuredData/context/state conditions) are outside the competition and always fire, like \"default\" and unconditional transitions. Criteria evaluation is unaffected — this arbitrates AFTER scoring, so it is the reliable way to get \"only one reasoning wins\" (independent per-criterion evaluations cannot be prompted into exclusivity).",
                                      "type": "string",
                                      "enum": [
                                        "all",
                                        "bestReasoning",
                                        "topReasonings"
                                      ]
                                    },
                                    "maxReasonings": {
                                      "description": "Only used when routingPolicy is \"topReasonings\": how many of the highest-scoring reasonings win the routing. Ignored for other policies (\"bestReasoning\" is exactly maxReasonings = 1).",
                                      "type": "integer",
                                      "minimum": 1,
                                      "maximum": 9007199254740991
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type",
                                    "evaluationCriteria",
                                    "transition"
                                  ]
                                },
                                {
                                  "oneOf": [
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "action"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this action node.",
                                          "type": "string"
                                        },
                                        "mode": {
                                          "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                          "type": "string",
                                          "enum": [
                                            "sync",
                                            "async"
                                          ]
                                        },
                                        "outputVar": {
                                          "description": "Variable name to store the action output for use by downstream nodes.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Transitions to other nodes after this action completes.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/createAgent_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        },
                                        "actionType": {
                                          "type": "string",
                                          "const": "INSTRUCTIONS"
                                        },
                                        "config": {
                                          "type": "object",
                                          "properties": {
                                            "instructions": {
                                              "description": "The instructions for the LLM to execute.",
                                              "type": "string"
                                            },
                                            "modelTier": {
                                              "description": "The model tier to use for this instruction. Defaults to regular.",
                                              "type": "string",
                                              "enum": [
                                                "lite",
                                                "regular",
                                                "pro"
                                              ]
                                            },
                                            "thinkingEffortPct": {
                                              "description": "Thinking effort percentage (0-100) controlling how much reasoning the model applies.",
                                              "type": "number",
                                              "minimum": 0,
                                              "maximum": 100
                                            },
                                            "maxOutputTokens": {
                                              "description": "Maximum tokens the model may generate for this node. On thinking models the budget is SHARED between reasoning and output — reasoning routinely consumes most of it — so a node whose structured output is truncated is usually better served by lowering thinkingEffortPct than by raising this. Defaults to the model maximum when omitted.",
                                              "type": "integer",
                                              "minimum": 1,
                                              "maximum": 9007199254740991
                                            },
                                            "maxRetries": {
                                              "description": "How many times this node retries a failed model call. Defaults to 2 when the node has an outputSchema and 5 otherwise. Raise it for nodes whose long outputs are exposed to dropped provider streams; it does not help failures the model reproduces deterministically.",
                                              "type": "integer",
                                              "minimum": 1,
                                              "maximum": 10
                                            },
                                            "toolChoiceMode": {
                                              "description": "Tool selection mode for this instruction. Defaults to auto when omitted.",
                                              "type": "string",
                                              "enum": [
                                                "auto",
                                                "none",
                                                "tool",
                                                "tools"
                                              ]
                                            },
                                            "toolChoiceToolName": {
                                              "description": "When toolChoiceMode is \"tool\", the specific tool name to force.",
                                              "type": "string"
                                            },
                                            "toolChoiceToolNames": {
                                              "description": "When toolChoiceMode is \"tools\", the list of allowed tool names.",
                                              "type": "array",
                                              "items": {
                                                "type": "string"
                                              }
                                            },
                                            "suppressTextResponse": {
                                              "description": "When true, text output from the LLM is suppressed and only tool-call results are emitted. Useful when the instruction should only invoke tools (e.g., displayMedia) without generating follow-up text.",
                                              "type": "boolean"
                                            },
                                            "stopAfterFirstToolCall": {
                                              "description": "When true and a single tool is forced with text suppressed, the instruction stops after the first successful tool call. Defaults to false, which allows the tool to be called across multiple steps.",
                                              "type": "boolean"
                                            },
                                            "internal": {
                                              "description": "When true, this node is an intermediate step: its text/structured output is NOT shown to the user (not streamed, not persisted as a visible message part) and is only captured into the node's outputVar for downstream nodes. Reasoning and tool-call activity chips remain visible. Use for internal hand-offs (e.g. tool-driven data synthesis a later node consumes); the user-facing reply should come from a later, non-internal node.",
                                              "type": "boolean"
                                            },
                                            "outputSchema": {
                                              "description": "JSON Schema for structured output. When provided, the LLM will output valid JSON matching this schema instead of free-form text.",
                                              "type": "object",
                                              "properties": {
                                                "type": {
                                                  "description": "JSON Schema type, must be \"object\" for structured output.",
                                                  "type": "string",
                                                  "const": "object"
                                                },
                                                "properties": {
                                                  "description": "Schema properties defining the expected output structure.",
                                                  "type": "object",
                                                  "propertyNames": {
                                                    "type": "string"
                                                  },
                                                  "additionalProperties": {}
                                                },
                                                "required": {
                                                  "description": "Array of required property names.",
                                                  "type": "array",
                                                  "items": {
                                                    "type": "string"
                                                  }
                                                },
                                                "additionalProperties": {
                                                  "description": "Whether to allow additional properties not defined in the schema.",
                                                  "type": "boolean"
                                                },
                                                "description": {
                                                  "description": "Description of the expected output to guide the LLM.",
                                                  "type": "string"
                                                }
                                              },
                                              "required": [
                                                "type",
                                                "properties"
                                              ]
                                            },
                                            "grounding": {
                                              "description": "Model-side grounding for this node. Only Google Search is available today.",
                                              "type": "object",
                                              "properties": {
                                                "googleSearch": {
                                                  "description": "Enable Google Search grounding: the model searches the public web (via Gemini's built-in google_search tool) while executing this instruction and answers from what it finds. Set `{}` to enable with defaults. The node result then carries `grounding` — the queries Google ran and the sources it cited, each with the resolved article URL, its domain and the passages of the reply it supports — readable downstream as `nodes.<nodeId>.grounding` in javascript nodes and templates; the text/JSON reply itself still flows through outputVar as usual. With an outputSchema the search runs first and the JSON is synthesized afterwards with the numbered source list, so declare a `sourceIds` or `url` field if you want citations inside the structured output. Incompatible with toolChoiceMode \"tool\" and with suppressTextResponse (a forced tool call and Google Search in one request returns an empty reply); with toolChoiceMode \"none\" the node still searches but calls no other tool. Each prompt costs Google one search query per query the model decides to run (usually 4–10), billed per query beyond the project's free tier.",
                                                  "type": "object",
                                                  "properties": {
                                                    "excludeDomains": {
                                                      "description": "Domains Google Search must not ground on, e.g. [\"youtube.com\", \"reddit.com\"]. A domain excludes its subdomains too.",
                                                      "type": "array",
                                                      "items": {
                                                        "type": "string"
                                                      }
                                                    }
                                                  }
                                                }
                                              }
                                            },
                                            "urlContext": {
                                              "description": "Gemini URL context: hand the model a list of URLs to READ IN FULL server-side instead of fetching their text into a variable first. The URLs come from the fixed \"urls\" list, from the \"from\" value path, or from both (fixed first). They are appended to the end of the instruction and the provider fetches and reads the pages inside the same call. With an outputSchema the node runs as a SINGLE call (reading and synthesis must share it), so pair it with toolChoiceMode \"none\" unless the node truly needs function tools. Limits: 20 URLs per call (extra ones are dropped and reported as `truncated`), public pages only — paywalls, Google News redirect links and private hosts fail. The model may skip fetching when the URLs sit inside a very long prompt, so prefer a dedicated short reading node over bolting URLs onto a large synthesis prompt. The node output carries `urlContext.{requested,retrieved,unread,truncated,invalid,unresolved,supported,tokens}`. `unread` is the integrity signal — it lists every URL the model did not read, including the ones dropped by the 20-URL cap — so branch on `nodes.<id>.urlContext.unread` for a fallback reader (inside a forEach body it holds only the last item). `unresolved` says the \"from\" path resolved to nothing, `invalid` lists entries that were not http(s) URLs, and `supported` is false when the model could not carry the tool: in those cases nothing was read at all. Retrieved page content is billed as input tokens and added to the node usage as `urlContextTokens`. Gemini 3+ models only.",
                                              "type": "object",
                                              "properties": {
                                                "urls": {
                                                  "description": "Fixed http(s) URLs to read on every run, written out here — for pages that do not change per execution (a status page, a policy, a price list). Combine with \"from\" to read a fixed set plus whatever the run produced; the two lists concatenate, fixed URLs first.",
                                                  "type": "array",
                                                  "items": {
                                                    "type": "string"
                                                  }
                                                },
                                                "from": {
                                                  "description": "Dotted VALUE PATH (same resolution as forEach \"over\": workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — e.g. \"paraLer.soUrls\" or \"nodes.pick.result.urls\") to a URL list the run produced: an array of http(s) URL strings, a single URL string, or a JSON-encoded array string. Not a Handlebars template; a path wrapped in {{ }} is accepted and unwrapped.",
                                                  "type": "string",
                                                  "minLength": 1
                                                }
                                              }
                                            }
                                          },
                                          "required": [
                                            "instructions"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "mode",
                                        "transition",
                                        "actionType",
                                        "config"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "action"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this action node.",
                                          "type": "string"
                                        },
                                        "mode": {
                                          "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                          "type": "string",
                                          "enum": [
                                            "sync",
                                            "async"
                                          ]
                                        },
                                        "outputVar": {
                                          "description": "Variable name to store the action output for use by downstream nodes.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Transitions to other nodes after this action completes.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/createAgent_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        },
                                        "actionType": {
                                          "type": "string",
                                          "const": "EMAIL"
                                        },
                                        "config": {
                                          "type": "object",
                                          "properties": {
                                            "to": {
                                              "type": "string"
                                            },
                                            "senderType": {
                                              "type": "string",
                                              "enum": [
                                                "default",
                                                "gmail"
                                              ]
                                            },
                                            "gmailIntegrationId": {
                                              "type": "string"
                                            },
                                            "subject": {
                                              "type": "string"
                                            },
                                            "body": {
                                              "type": "string"
                                            },
                                            "cc": {
                                              "type": "string"
                                            },
                                            "bcc": {
                                              "type": "string"
                                            },
                                            "attachments": {
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "documentId": {
                                                    "type": "number"
                                                  },
                                                  "url": {
                                                    "type": "string"
                                                  },
                                                  "filename": {
                                                    "type": "string"
                                                  }
                                                }
                                              }
                                            },
                                            "templateId": {
                                              "type": "string"
                                            },
                                            "templateName": {
                                              "type": "string"
                                            },
                                            "applicationId": {
                                              "type": "number"
                                            }
                                          },
                                          "required": [
                                            "to",
                                            "subject",
                                            "body"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "mode",
                                        "transition",
                                        "actionType",
                                        "config"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "action"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this action node.",
                                          "type": "string"
                                        },
                                        "mode": {
                                          "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                          "type": "string",
                                          "enum": [
                                            "sync",
                                            "async"
                                          ]
                                        },
                                        "outputVar": {
                                          "description": "Variable name to store the action output for use by downstream nodes.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Transitions to other nodes after this action completes.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/createAgent_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        },
                                        "actionType": {
                                          "type": "string",
                                          "const": "WEBHOOK"
                                        },
                                        "config": {
                                          "type": "object",
                                          "properties": {
                                            "url": {
                                              "type": "string"
                                            },
                                            "method": {
                                              "type": "string",
                                              "enum": [
                                                "GET",
                                                "POST",
                                                "PUT",
                                                "PATCH",
                                                "DELETE"
                                              ]
                                            },
                                            "headers": {
                                              "type": "object",
                                              "propertyNames": {
                                                "type": "string"
                                              },
                                              "additionalProperties": {
                                                "type": "string"
                                              }
                                            },
                                            "queryParams": {
                                              "type": "object",
                                              "propertyNames": {
                                                "type": "string"
                                              },
                                              "additionalProperties": {
                                                "type": "string"
                                              }
                                            },
                                            "body": {
                                              "type": "string"
                                            },
                                            "timeout": {
                                              "type": "number"
                                            },
                                            "responseMode": {
                                              "description": "How to decode the response body. \"json\" (default): parse as JSON/text and expose via varsDelta. \"attachment\": read as binary bytes for multimodal input (e.g. PDFs, images).",
                                              "type": "string",
                                              "enum": [
                                                "json",
                                                "attachment"
                                              ]
                                            },
                                            "asMessage": {
                                              "description": "When true, append the response to the conversation as a new user message so downstream LLM nodes see it. In \"attachment\" mode the message carries a file content part; in \"json\" mode it carries the stringified body as text. Defaults to false — preserving the historical behavior where webhook responses only flow through varsDelta.",
                                              "type": "boolean"
                                            },
                                            "suppressNoResponseFallback": {
                                              "description": "Marks the webhook as a fire-and-forget trigger: the conversation is meant to end here, with the rest happening on the receiving system. When the call succeeds and the turn finishes without sending anything to the user, the channel skips its automatic \"sorry, something went wrong\" fallback message. A failed call (HTTP >= 400) still gets the fallback, since the user is then left waiting for nothing.",
                                              "type": "boolean"
                                            }
                                          },
                                          "required": [
                                            "url",
                                            "method"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "mode",
                                        "transition",
                                        "actionType",
                                        "config"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "action"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this action node.",
                                          "type": "string"
                                        },
                                        "mode": {
                                          "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                          "type": "string",
                                          "enum": [
                                            "sync",
                                            "async"
                                          ]
                                        },
                                        "outputVar": {
                                          "description": "Variable name to store the action output for use by downstream nodes.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Transitions to other nodes after this action completes.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/createAgent_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        },
                                        "actionType": {
                                          "type": "string",
                                          "const": "DOCUMENT_TEMPLATE"
                                        },
                                        "config": {
                                          "type": "object",
                                          "properties": {
                                            "templateId": {
                                              "type": "string"
                                            },
                                            "templateName": {
                                              "type": "string"
                                            },
                                            "sendEmail": {
                                              "type": "boolean"
                                            },
                                            "sendWhatsApp": {
                                              "type": "boolean"
                                            },
                                            "recipientEmail": {
                                              "type": "string"
                                            }
                                          },
                                          "required": [
                                            "templateId"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "mode",
                                        "transition",
                                        "actionType",
                                        "config"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "action"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this action node.",
                                          "type": "string"
                                        },
                                        "mode": {
                                          "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                          "type": "string",
                                          "enum": [
                                            "sync",
                                            "async"
                                          ]
                                        },
                                        "outputVar": {
                                          "description": "Variable name to store the action output for use by downstream nodes.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Transitions to other nodes after this action completes.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/createAgent_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        },
                                        "actionType": {
                                          "type": "string",
                                          "const": "TOOL_CALL"
                                        },
                                        "config": {
                                          "type": "object",
                                          "properties": {
                                            "toolName": {
                                              "description": "The name of the common tool to invoke.",
                                              "type": "string"
                                            },
                                            "parameters": {
                                              "description": "Per-parameter configuration. Keys are parameter names from the tool schema.",
                                              "type": "object",
                                              "propertyNames": {
                                                "type": "string"
                                              },
                                              "additionalProperties": {
                                                "type": "object",
                                                "properties": {
                                                  "mode": {
                                                    "description": "Whether this parameter is hardcoded (static) or filled by the LLM at runtime (dynamic).",
                                                    "type": "string",
                                                    "enum": [
                                                      "static",
                                                      "dynamic"
                                                    ]
                                                  },
                                                  "staticValue": {
                                                    "description": "The fixed value for this parameter. Required when mode is \"static\"."
                                                  },
                                                  "instructions": {
                                                    "description": "Optional guidance for the LLM when filling this parameter (only used when mode is \"dynamic\").",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "mode"
                                                ]
                                              }
                                            },
                                            "instructions": {
                                              "description": "General instructions for the LLM when resolving dynamic parameters.",
                                              "type": "string"
                                            },
                                            "skipKnowledgeSearch": {
                                              "description": "When a node has dynamic parameters, the model is normally forced to call similaritySearch first so parameter values are grounded in the knowledge base, costing one extra model round. Set true for tools that need no knowledge context (for example code execution) to call the configured tool directly. Ignored when every parameter is static, since no model runs at all.",
                                              "type": "boolean"
                                            }
                                          },
                                          "required": [
                                            "toolName"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "mode",
                                        "transition",
                                        "actionType",
                                        "config"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "action"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this action node.",
                                          "type": "string"
                                        },
                                        "mode": {
                                          "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                          "type": "string",
                                          "enum": [
                                            "sync",
                                            "async"
                                          ]
                                        },
                                        "outputVar": {
                                          "description": "Variable name to store the action output for use by downstream nodes.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Transitions to other nodes after this action completes.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/createAgent_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        },
                                        "actionType": {
                                          "type": "string",
                                          "const": "FOLLOW_UP"
                                        },
                                        "config": {
                                          "type": "object",
                                          "properties": {
                                            "delayMinutes": {
                                              "description": "Minutes to wait before checking whether to run the inner action. Common presets: 5, 10, 15. Maximum 1440 (24h). Cloud Scheduler is cron-based so the actual fire time is rounded to the next minute boundary.",
                                              "type": "integer",
                                              "minimum": 1,
                                              "maximum": 1440
                                            },
                                            "cancelOnUserMessage": {
                                              "description": "When true (default), skip the inner action if any USER message arrived after the node was reached. Set to false only if the follow-up should fire even after the user has replied.",
                                              "type": "boolean"
                                            },
                                            "cancelOnAssistantMessage": {
                                              "description": "When true (default), skip the inner action if any ASSISTANT text message was sent after the node was reached. Tool-only assistant messages (no text content) do NOT count. Prevents double-pinging when another node already produced a response.",
                                              "type": "boolean"
                                            },
                                            "cancelOnArchive": {
                                              "description": "When true (default), skip the inner action if the thread was archived between scheduling and firing.",
                                              "type": "boolean"
                                            },
                                            "action": {
                                              "description": "The inner action to run when the delay elapses and cancel rules pass. INSTRUCTIONS produces an LLM-generated text message (good for \"Are you still there?\"-style nudges). TOOL_CALL fires a display tool (good for offering options or showing media).",
                                              "oneOf": [
                                                {
                                                  "type": "object",
                                                  "properties": {
                                                    "actionType": {
                                                      "type": "string",
                                                      "const": "INSTRUCTIONS"
                                                    },
                                                    "config": {
                                                      "type": "object",
                                                      "properties": {
                                                        "instructions": {
                                                          "description": "The instructions for the LLM to execute.",
                                                          "type": "string"
                                                        },
                                                        "modelTier": {
                                                          "description": "The model tier to use for this instruction. Defaults to regular.",
                                                          "type": "string",
                                                          "enum": [
                                                            "lite",
                                                            "regular",
                                                            "pro"
                                                          ]
                                                        },
                                                        "thinkingEffortPct": {
                                                          "description": "Thinking effort percentage (0-100) controlling how much reasoning the model applies.",
                                                          "type": "number",
                                                          "minimum": 0,
                                                          "maximum": 100
                                                        },
                                                        "maxOutputTokens": {
                                                          "description": "Maximum tokens the model may generate for this node. On thinking models the budget is SHARED between reasoning and output — reasoning routinely consumes most of it — so a node whose structured output is truncated is usually better served by lowering thinkingEffortPct than by raising this. Defaults to the model maximum when omitted.",
                                                          "type": "integer",
                                                          "minimum": 1,
                                                          "maximum": 9007199254740991
                                                        },
                                                        "maxRetries": {
                                                          "description": "How many times this node retries a failed model call. Defaults to 2 when the node has an outputSchema and 5 otherwise. Raise it for nodes whose long outputs are exposed to dropped provider streams; it does not help failures the model reproduces deterministically.",
                                                          "type": "integer",
                                                          "minimum": 1,
                                                          "maximum": 10
                                                        },
                                                        "toolChoiceMode": {
                                                          "description": "Tool selection mode for this instruction. Defaults to auto when omitted.",
                                                          "type": "string",
                                                          "enum": [
                                                            "auto",
                                                            "none",
                                                            "tool",
                                                            "tools"
                                                          ]
                                                        },
                                                        "toolChoiceToolName": {
                                                          "description": "When toolChoiceMode is \"tool\", the specific tool name to force.",
                                                          "type": "string"
                                                        },
                                                        "toolChoiceToolNames": {
                                                          "description": "When toolChoiceMode is \"tools\", the list of allowed tool names.",
                                                          "type": "array",
                                                          "items": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "suppressTextResponse": {
                                                          "description": "When true, text output from the LLM is suppressed and only tool-call results are emitted. Useful when the instruction should only invoke tools (e.g., displayMedia) without generating follow-up text.",
                                                          "type": "boolean"
                                                        },
                                                        "stopAfterFirstToolCall": {
                                                          "description": "When true and a single tool is forced with text suppressed, the instruction stops after the first successful tool call. Defaults to false, which allows the tool to be called across multiple steps.",
                                                          "type": "boolean"
                                                        },
                                                        "internal": {
                                                          "description": "When true, this node is an intermediate step: its text/structured output is NOT shown to the user (not streamed, not persisted as a visible message part) and is only captured into the node's outputVar for downstream nodes. Reasoning and tool-call activity chips remain visible. Use for internal hand-offs (e.g. tool-driven data synthesis a later node consumes); the user-facing reply should come from a later, non-internal node.",
                                                          "type": "boolean"
                                                        },
                                                        "outputSchema": {
                                                          "description": "JSON Schema for structured output. When provided, the LLM will output valid JSON matching this schema instead of free-form text.",
                                                          "type": "object",
                                                          "properties": {
                                                            "type": {
                                                              "description": "JSON Schema type, must be \"object\" for structured output.",
                                                              "type": "string",
                                                              "const": "object"
                                                            },
                                                            "properties": {
                                                              "description": "Schema properties defining the expected output structure.",
                                                              "type": "object",
                                                              "propertyNames": {
                                                                "type": "string"
                                                              },
                                                              "additionalProperties": {}
                                                            },
                                                            "required": {
                                                              "description": "Array of required property names.",
                                                              "type": "array",
                                                              "items": {
                                                                "type": "string"
                                                              }
                                                            },
                                                            "additionalProperties": {
                                                              "description": "Whether to allow additional properties not defined in the schema.",
                                                              "type": "boolean"
                                                            },
                                                            "description": {
                                                              "description": "Description of the expected output to guide the LLM.",
                                                              "type": "string"
                                                            }
                                                          },
                                                          "required": [
                                                            "type",
                                                            "properties"
                                                          ]
                                                        },
                                                        "grounding": {
                                                          "description": "Model-side grounding for this node. Only Google Search is available today.",
                                                          "type": "object",
                                                          "properties": {
                                                            "googleSearch": {
                                                              "description": "Enable Google Search grounding: the model searches the public web (via Gemini's built-in google_search tool) while executing this instruction and answers from what it finds. Set `{}` to enable with defaults. The node result then carries `grounding` — the queries Google ran and the sources it cited, each with the resolved article URL, its domain and the passages of the reply it supports — readable downstream as `nodes.<nodeId>.grounding` in javascript nodes and templates; the text/JSON reply itself still flows through outputVar as usual. With an outputSchema the search runs first and the JSON is synthesized afterwards with the numbered source list, so declare a `sourceIds` or `url` field if you want citations inside the structured output. Incompatible with toolChoiceMode \"tool\" and with suppressTextResponse (a forced tool call and Google Search in one request returns an empty reply); with toolChoiceMode \"none\" the node still searches but calls no other tool. Each prompt costs Google one search query per query the model decides to run (usually 4–10), billed per query beyond the project's free tier.",
                                                              "type": "object",
                                                              "properties": {
                                                                "excludeDomains": {
                                                                  "description": "Domains Google Search must not ground on, e.g. [\"youtube.com\", \"reddit.com\"]. A domain excludes its subdomains too.",
                                                                  "type": "array",
                                                                  "items": {
                                                                    "type": "string"
                                                                  }
                                                                }
                                                              }
                                                            }
                                                          }
                                                        },
                                                        "urlContext": {
                                                          "description": "Gemini URL context: hand the model a list of URLs to READ IN FULL server-side instead of fetching their text into a variable first. The URLs come from the fixed \"urls\" list, from the \"from\" value path, or from both (fixed first). They are appended to the end of the instruction and the provider fetches and reads the pages inside the same call. With an outputSchema the node runs as a SINGLE call (reading and synthesis must share it), so pair it with toolChoiceMode \"none\" unless the node truly needs function tools. Limits: 20 URLs per call (extra ones are dropped and reported as `truncated`), public pages only — paywalls, Google News redirect links and private hosts fail. The model may skip fetching when the URLs sit inside a very long prompt, so prefer a dedicated short reading node over bolting URLs onto a large synthesis prompt. The node output carries `urlContext.{requested,retrieved,unread,truncated,invalid,unresolved,supported,tokens}`. `unread` is the integrity signal — it lists every URL the model did not read, including the ones dropped by the 20-URL cap — so branch on `nodes.<id>.urlContext.unread` for a fallback reader (inside a forEach body it holds only the last item). `unresolved` says the \"from\" path resolved to nothing, `invalid` lists entries that were not http(s) URLs, and `supported` is false when the model could not carry the tool: in those cases nothing was read at all. Retrieved page content is billed as input tokens and added to the node usage as `urlContextTokens`. Gemini 3+ models only.",
                                                          "type": "object",
                                                          "properties": {
                                                            "urls": {
                                                              "description": "Fixed http(s) URLs to read on every run, written out here — for pages that do not change per execution (a status page, a policy, a price list). Combine with \"from\" to read a fixed set plus whatever the run produced; the two lists concatenate, fixed URLs first.",
                                                              "type": "array",
                                                              "items": {
                                                                "type": "string"
                                                              }
                                                            },
                                                            "from": {
                                                              "description": "Dotted VALUE PATH (same resolution as forEach \"over\": workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — e.g. \"paraLer.soUrls\" or \"nodes.pick.result.urls\") to a URL list the run produced: an array of http(s) URL strings, a single URL string, or a JSON-encoded array string. Not a Handlebars template; a path wrapped in {{ }} is accepted and unwrapped.",
                                                              "type": "string",
                                                              "minLength": 1
                                                            }
                                                          }
                                                        }
                                                      },
                                                      "required": [
                                                        "instructions"
                                                      ]
                                                    }
                                                  },
                                                  "required": [
                                                    "actionType",
                                                    "config"
                                                  ]
                                                },
                                                {
                                                  "type": "object",
                                                  "properties": {
                                                    "actionType": {
                                                      "type": "string",
                                                      "const": "TOOL_CALL"
                                                    },
                                                    "config": {
                                                      "type": "object",
                                                      "properties": {
                                                        "toolName": {
                                                          "description": "The name of the common tool to invoke.",
                                                          "type": "string"
                                                        },
                                                        "parameters": {
                                                          "description": "Per-parameter configuration. Keys are parameter names from the tool schema.",
                                                          "type": "object",
                                                          "propertyNames": {
                                                            "type": "string"
                                                          },
                                                          "additionalProperties": {
                                                            "type": "object",
                                                            "properties": {
                                                              "mode": {
                                                                "description": "Whether this parameter is hardcoded (static) or filled by the LLM at runtime (dynamic).",
                                                                "type": "string",
                                                                "enum": [
                                                                  "static",
                                                                  "dynamic"
                                                                ]
                                                              },
                                                              "staticValue": {
                                                                "description": "The fixed value for this parameter. Required when mode is \"static\"."
                                                              },
                                                              "instructions": {
                                                                "description": "Optional guidance for the LLM when filling this parameter (only used when mode is \"dynamic\").",
                                                                "type": "string"
                                                              }
                                                            },
                                                            "required": [
                                                              "mode"
                                                            ]
                                                          }
                                                        },
                                                        "instructions": {
                                                          "description": "General instructions for the LLM when resolving dynamic parameters.",
                                                          "type": "string"
                                                        },
                                                        "skipKnowledgeSearch": {
                                                          "description": "When a node has dynamic parameters, the model is normally forced to call similaritySearch first so parameter values are grounded in the knowledge base, costing one extra model round. Set true for tools that need no knowledge context (for example code execution) to call the configured tool directly. Ignored when every parameter is static, since no model runs at all.",
                                                          "type": "boolean"
                                                        }
                                                      },
                                                      "required": [
                                                        "toolName"
                                                      ]
                                                    }
                                                  },
                                                  "required": [
                                                    "actionType",
                                                    "config"
                                                  ]
                                                }
                                              ]
                                            }
                                          },
                                          "required": [
                                            "delayMinutes",
                                            "action"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "mode",
                                        "transition",
                                        "actionType",
                                        "config"
                                      ]
                                    }
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "subAgent"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this sub-agent node.",
                                      "type": "string"
                                    },
                                    "agentId": {
                                      "description": "The ID of the sub-agent to invoke.",
                                      "type": "string"
                                    },
                                    "instructions": {
                                      "description": "Optional instructions message prepended to the sub-agent conversation. Supports Handlebars interpolation against the parent execution scope: `{{var}}` reads workflow vars, `{{context.x}}` reads contextVars, `{{env.X}}` reads environment, `{{input.text}}` reads the original user input, and `{{nodes.<id>.<path>}}` reads prior node outputs.",
                                      "type": "string"
                                    },
                                    "transition": {
                                      "description": "Optional transitions to continue the flow after the sub-agent returns.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/createAgent_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type",
                                    "agentId"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "end"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this end node.",
                                      "type": "string"
                                    },
                                    "config": {
                                      "description": "Optional configuration for the end node behavior.",
                                      "type": "object",
                                      "properties": {
                                        "resetConversationHistory": {
                                          "description": "If true, the next user message starts a new conversation with no prior history.",
                                          "type": "boolean"
                                        }
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "state"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this state node.",
                                      "type": "string"
                                    },
                                    "outputVar": {
                                      "description": "Agent-scope get only: variable name that receives the value stored under `config.key` (null when the key has never been written). Downstream templates read it as `{{<outputVar>}}`; transition conditions as `{source:\"vars\", path:\"<outputVar>...\"}`.",
                                      "type": "string"
                                    },
                                    "config": {
                                      "type": "object",
                                      "properties": {
                                        "scope": {
                                          "description": "How long the data lives and who sees it. execution: this run only. session: this conversation (thread) — a NEW conversation starts empty. agent: durable memory shared by every execution of this agent, across conversations — use it to remember things between independent runs. Survives clearCache.",
                                          "type": "string",
                                          "enum": [
                                            "execution",
                                            "session",
                                            "agent"
                                          ]
                                        },
                                        "operation": {
                                          "description": "Agent scope only (default set). set: durably store the `state` entries. get: read the entry under `key` into `outputVar`. Execution/session scopes are always set — their values are injected into templates automatically, so no get is needed.",
                                          "type": "string",
                                          "enum": [
                                            "set",
                                            "get"
                                          ]
                                        },
                                        "key": {
                                          "description": "Agent-scope get: the memory key to read. Supports Handlebars (e.g. \"evidence-{{context.cnpj}}\") so one node can address per-entity entries. Rendered keys are limited to 512 characters.",
                                          "type": "string"
                                        },
                                        "state": {
                                          "description": "Key-value pairs to set (required for set operations). String values support Handlebars. In agent scope the KEYS are templates too (e.g. \"evidence-{{context.cnpj}}\"), each entry is stored as its own durable row, and serialized values are size-capped.",
                                          "type": "object",
                                          "propertyNames": {
                                            "type": "string"
                                          },
                                          "additionalProperties": {}
                                        }
                                      },
                                      "required": [
                                        "scope"
                                      ]
                                    },
                                    "transition": {
                                      "description": "Optional transitions to continue the flow after setting state.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/createAgent_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type",
                                    "config"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "hub"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this hub node.",
                                      "type": "string"
                                    },
                                    "transition": {
                                      "description": "Transitions to route connections to other nodes.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/createAgent_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "jump"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this jump node.",
                                      "type": "string"
                                    },
                                    "transition": {
                                      "description": "Target node to jump to unconditionally.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/createAgent_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "clearCache"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this clear cache node.",
                                      "type": "string"
                                    },
                                    "config": {
                                      "description": "Optional configuration controlling what is cleared.",
                                      "type": "object",
                                      "properties": {
                                        "clearScope": {
                                          "description": "What to clear. executionCache (default): clears only the decision result cache. all: clears the entire session state including user-defined session variables.",
                                          "type": "string",
                                          "enum": [
                                            "executionCache",
                                            "all"
                                          ]
                                        }
                                      }
                                    },
                                    "transition": {
                                      "description": "Optional transitions to continue the flow after clearing cache.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/createAgent_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "javascript"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this JavaScript node.",
                                      "type": "string"
                                    },
                                    "outputVar": {
                                      "description": "Variable name to store the returned value for downstream nodes. Downstream templates read it as `{{<outputVar>}}`; transition conditions as `{source:\"vars\", path:\"<outputVar>...\"}`.",
                                      "type": "string"
                                    },
                                    "config": {
                                      "type": "object",
                                      "properties": {
                                        "code": {
                                          "description": "JavaScript source executed in a sandboxed QuickJS interpreter. Written as a function body: it receives ({ vars, evaluation, context, env, input, nodes }) and must `return` a JSON-serializable value. Synchronous only — no network, filesystem, require/import, or timers.",
                                          "type": "string"
                                        },
                                        "timeoutMs": {
                                          "description": "CPU deadline in milliseconds. Default 1000, max 10000.",
                                          "type": "integer",
                                          "minimum": 1,
                                          "maximum": 10000
                                        }
                                      },
                                      "required": [
                                        "code"
                                      ]
                                    },
                                    "transition": {
                                      "description": "Optional transitions to continue the flow after the code runs.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/createAgent_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type",
                                    "config"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "forEach"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this forEach node.",
                                      "type": "string"
                                    },
                                    "over": {
                                      "description": "Dotted path to the array to iterate, resolved against the execution scope: top-level workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — for example \"research.socioAlvos\" or \"nodes.build_plan.result.targets\". This is a VALUE PATH, not a Handlebars template: Handlebars renders to a string, so an array passed through it would arrive as \"[object Object]\". A path wrapped in {{ }} is accepted and unwrapped. If the path does not resolve to an array the node fails loudly instead of iterating a string.",
                                      "type": "string"
                                    },
                                    "as": {
                                      "description": "Variable name bound to the current element inside the body node: \"socio\" makes {{socio.nome}} available to the body's templates. Must not be \"iteration\", which is reserved for the {index, total} binding also exposed to the body.",
                                      "type": "string"
                                    },
                                    "each": {
                                      "description": "The body node, referenced by ID. Must be an action, javascript or subAgent node declared in workflow.nodes with no other incoming transitions, and must not be an entry point. Its own \"transition\" array is ignored — the forEach node owns what happens after every item finishes. decision nodes are rejected because the execution cache is keyed by node ID, so parallel instances would contend for one cache entry.",
                                      "type": "object",
                                      "properties": {
                                        "nodeId": {
                                          "description": "The ID of the node to run once per item.",
                                          "type": "string"
                                        }
                                      },
                                      "required": [
                                        "nodeId"
                                      ]
                                    },
                                    "collectInto": {
                                      "description": "Variable name receiving the per-item results array. Each entry is {index, item, ok, value?, grounding?, error?, errorName?}, where \"value\" is whatever the body node's own outputVar would have held (undefined when the body declares none) and \"grounding\" is that item's Google Search queries and sources when the body is a grounded INSTRUCTIONS node — the same shape a standalone node exposes as nodes.<id>.grounding. Entries stay aligned with the source array by index, including failed items, so a downstream node can tell \"this item returned nothing\" apart from \"this item was never tried\". Omit only if nothing downstream needs the results.",
                                      "type": "string"
                                    },
                                    "maxConcurrency": {
                                      "description": "How many items run at once. Defaults to 5. Raise carefully: per-item parallelism hits provider rate limits well before it hits platform limits.",
                                      "type": "integer",
                                      "minimum": 1,
                                      "maximum": 20
                                    },
                                    "transition": {
                                      "description": "Transitions to continue the flow after every item has finished.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/createAgent_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type",
                                    "over",
                                    "as",
                                    "each"
                                  ]
                                }
                              ]
                            }
                          }
                        },
                        "required": [
                          "toolName",
                          "toolDescription",
                          "entryPoints",
                          "nodes"
                        ]
                      },
                      "tools": {
                        "deprecated": true,
                        "description": "Deprecated and ignored. Tool availability is configured by the application, not the agent spec.",
                        "type": "array",
                        "items": {}
                      },
                      "metadata": {
                        "description": "Arbitrary metadata for custom extensions. Not used by the execution engine.",
                        "type": "object",
                        "propertyNames": {
                          "type": "string"
                        },
                        "additionalProperties": {}
                      }
                    },
                    "required": [
                      "version",
                      "name",
                      "prompt",
                      "workflow"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "applicationId",
                  "name",
                  "spec"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The new unpublished draft agent",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "Id assigned to the new agent.",
                      "type": "string"
                    },
                    "applicationId": {
                      "description": "Application that owns the agent.",
                      "type": "number"
                    },
                    "name": {
                      "description": "Agent display name.",
                      "type": "string"
                    },
                    "description": {
                      "description": "Agent description, or null when none was provided.",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "draft": {
                      "description": "Always true: creation never publishes an agent.",
                      "type": "boolean",
                      "const": true
                    },
                    "published": {
                      "description": "Always false: publish separately with `publishAgent`.",
                      "type": "boolean",
                      "const": false
                    },
                    "specArtifact": {
                      "description": "The linked spec artifact. Its storage-level kind is `json`; its first saved version is 1.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "version": {
                          "type": "number"
                        }
                      },
                      "required": [
                        "id",
                        "version"
                      ],
                      "additionalProperties": false
                    },
                    "warnings": {
                      "description": "Non-blocking validation warnings for the saved spec.",
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "id",
                    "applicationId",
                    "name",
                    "description",
                    "draft",
                    "published",
                    "specArtifact",
                    "warnings"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The spec has blocking mustFix validation defects",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Explanation of why the agent spec cannot be created yet.",
                      "type": "string"
                    },
                    "mustFix": {
                      "description": "Blocking spec defects that must be repaired before creation.",
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "warnings": {
                      "description": "Non-blocking spec advisories retained while repairing the request.",
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "error",
                    "mustFix",
                    "warnings"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/builder/": {
      "post": {
        "operationId": "runAgentBuilder",
        "summary": "Chat with the AI agent builder",
        "tags": [
          "agents"
        ],
        "description": "Converse with Docana's interactive agent-building expert. Two ways to use it: ask design questions (node types, transitions, why browsing tools are disabled, platform gotchas) even when authoring the spec yourself, or delegate the whole build and let it draft, validate, and import the spec. Streams an AI-SDK UI-message response. Body: `{ messages?, assistantContext: { applicationId, ... }, data? }`.",
        "x-docana-streaming": true,
        "requestBody": {
          "required": true,
          "description": "The conversation and context for the builder run.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "messages": {
                    "description": "The conversation so far. When omitted or null, the conversation starts empty.",
                    "type": "array",
                    "items": {
                      "description": "A conversation message in the AI SDK UI-message format.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "Unique id of the message within the conversation.",
                          "examples": [
                            "msg-4fT7aQ"
                          ],
                          "type": "string"
                        },
                        "role": {
                          "description": "Author of the message.",
                          "examples": [
                            "user"
                          ],
                          "type": "string",
                          "enum": [
                            "system",
                            "user",
                            "assistant"
                          ]
                        },
                        "parts": {
                          "description": "Ordered content parts of the message.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "type": {
                                "description": "Kind of the part, for example `text`.",
                                "examples": [
                                  "text"
                                ],
                                "type": "string"
                              },
                              "text": {
                                "description": "Text content. Present on `text` parts.",
                                "type": "string"
                              }
                            },
                            "required": [
                              "type"
                            ],
                            "additionalProperties": {}
                          }
                        }
                      },
                      "required": [
                        "id",
                        "role",
                        "parts"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "assistantContext": {
                    "description": "Context of the run. Additional fields such as `collectionIds`, `documentIds` or `interactionId` are passed through to the run.",
                    "type": "object",
                    "properties": {
                      "applicationId": {
                        "description": "Id of the application the run is scoped to. Required.",
                        "examples": [
                          42
                        ],
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "threadId": {
                        "description": "Id of an existing thread to continue. A new thread is created when omitted.",
                        "examples": [
                          "cmc5t2k9f0004l708d8yrn2q7"
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "applicationId"
                    ],
                    "additionalProperties": {}
                  },
                  "data": {
                    "description": "Extra flags for the stream.",
                    "type": "object",
                    "properties": {
                      "audioEnabled": {
                        "description": "When true, the response stream also carries synthesized speech for the assistant reply.",
                        "type": "boolean"
                      }
                    },
                    "additionalProperties": {}
                  }
                },
                "required": [
                  "assistantContext"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "UI-message event stream with the builder response"
          },
          "400": {
            "description": "Missing applicationId",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/diff/": {
      "post": {
        "operationId": "diffAgents",
        "summary": "Diff two agent specs",
        "tags": [
          "agents"
        ],
        "description": "Compares two agent specs and reports the semantic changes between them: workflow nodes added, removed or modified; reasonings (decision-node evaluation criteria, matched by name) added, removed or modified; nodes whose routing rules (transitions) changed; and changed top-level fields. Each side is an agent in this deployment (`agentId`) or an inline spec / export bundle (`spec`), so two different agents can be compared — for example a production agent against its development copy. Specs are normalized before comparison (ids and per-environment criteria references are neutralized), and the normalized specs are returned for stable textual diffs.",
        "x-docana-mcp-tool": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "left": {
                    "description": "The base of the comparison (for example the production agent).",
                    "type": "object",
                    "properties": {
                      "agentId": {
                        "description": "Id of an agent in this deployment.",
                        "examples": [
                          "cmc4v8xq10001l708h2vxk9d3"
                        ],
                        "type": "string",
                        "minLength": 1
                      },
                      "version": {
                        "description": "Spec version to compare, from the agent version history (see `listAgentSpecVersions`). Only valid together with `agentId`; omit for the current spec. Evaluation criteria referenced by DB id are inlined from their current rows, so historical versions show the criteria as they are today.",
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 9007199254740991
                      },
                      "spec": {
                        "description": "An inline agent spec, or a full agent export bundle whose root spec is used. Criteria-id normalization needs inline criteria entries carrying `id` and `name` (the shape `exportAgent` produces); bare string criteria references are compared as-is.",
                        "type": "object",
                        "propertyNames": {
                          "type": "string"
                        },
                        "additionalProperties": {}
                      }
                    }
                  },
                  "right": {
                    "description": "The side compared against the base (for example the dev agent).",
                    "type": "object",
                    "properties": {
                      "agentId": {
                        "description": "Id of an agent in this deployment.",
                        "examples": [
                          "cmc4v8xq10001l708h2vxk9d3"
                        ],
                        "type": "string",
                        "minLength": 1
                      },
                      "version": {
                        "description": "Spec version to compare, from the agent version history (see `listAgentSpecVersions`). Only valid together with `agentId`; omit for the current spec. Evaluation criteria referenced by DB id are inlined from their current rows, so historical versions show the criteria as they are today.",
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 9007199254740991
                      },
                      "spec": {
                        "description": "An inline agent spec, or a full agent export bundle whose root spec is used. Criteria-id normalization needs inline criteria entries carrying `id` and `name` (the shape `exportAgent` produces); bare string criteria references are compared as-is.",
                        "type": "object",
                        "propertyNames": {
                          "type": "string"
                        },
                        "additionalProperties": {}
                      }
                    }
                  }
                },
                "required": [
                  "left",
                  "right"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The semantic diff between the two specs",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "identical": {
                      "description": "True when the normalized specs are exactly equal.",
                      "type": "boolean"
                    },
                    "changes": {
                      "description": "The semantic changes going from `left` to `right`.",
                      "type": "object",
                      "properties": {
                        "nodes": {
                          "type": "object",
                          "properties": {
                            "added": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "description": "Workflow node id.",
                                    "type": "string"
                                  },
                                  "type": {
                                    "description": "Workflow node type, e.g. `decision` or `action`.",
                                    "type": "string"
                                  },
                                  "label": {
                                    "description": "Human-readable node label, when the spec has one.",
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "id",
                                  "type"
                                ],
                                "additionalProperties": false
                              }
                            },
                            "removed": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "description": "Workflow node id.",
                                    "type": "string"
                                  },
                                  "type": {
                                    "description": "Workflow node type, e.g. `decision` or `action`.",
                                    "type": "string"
                                  },
                                  "label": {
                                    "description": "Human-readable node label, when the spec has one.",
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "id",
                                  "type"
                                ],
                                "additionalProperties": false
                              }
                            },
                            "modified": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "description": "Workflow node id.",
                                    "type": "string"
                                  },
                                  "type": {
                                    "description": "Workflow node type, e.g. `decision` or `action`.",
                                    "type": "string"
                                  },
                                  "label": {
                                    "description": "Human-readable node label, when the spec has one.",
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "id",
                                  "type"
                                ],
                                "additionalProperties": false
                              }
                            }
                          },
                          "required": [
                            "added",
                            "removed",
                            "modified"
                          ],
                          "additionalProperties": false
                        },
                        "reasonings": {
                          "type": "object",
                          "properties": {
                            "added": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "nodeId": {
                                    "description": "Id of the decision node the reasoning belongs to.",
                                    "type": "string"
                                  },
                                  "name": {
                                    "description": "Name of the reasoning (evaluation criterion). Reasonings are matched by name.",
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "nodeId",
                                  "name"
                                ],
                                "additionalProperties": false
                              }
                            },
                            "removed": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "nodeId": {
                                    "description": "Id of the decision node the reasoning belongs to.",
                                    "type": "string"
                                  },
                                  "name": {
                                    "description": "Name of the reasoning (evaluation criterion). Reasonings are matched by name.",
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "nodeId",
                                  "name"
                                ],
                                "additionalProperties": false
                              }
                            },
                            "modified": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "nodeId": {
                                    "description": "Id of the decision node the reasoning belongs to.",
                                    "type": "string"
                                  },
                                  "name": {
                                    "description": "Name of the reasoning (evaluation criterion). Reasonings are matched by name.",
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "nodeId",
                                  "name"
                                ],
                                "additionalProperties": false
                              }
                            }
                          },
                          "required": [
                            "added",
                            "removed",
                            "modified"
                          ],
                          "additionalProperties": false
                        },
                        "routingChanged": {
                          "description": "Nodes whose outgoing transitions (routing rules) changed.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "description": "Workflow node id.",
                                "type": "string"
                              },
                              "type": {
                                "description": "Workflow node type, e.g. `decision` or `action`.",
                                "type": "string"
                              },
                              "label": {
                                "description": "Human-readable node label, when the spec has one.",
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "type"
                            ],
                            "additionalProperties": false
                          }
                        },
                        "changedTopLevelFields": {
                          "description": "Top-level spec fields outside workflow nodes that changed, e.g. `prompt` or `llm`.",
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      },
                      "required": [
                        "nodes",
                        "reasonings",
                        "routingChanged",
                        "changedTopLevelFields"
                      ],
                      "additionalProperties": false
                    },
                    "left": {
                      "type": "object",
                      "properties": {
                        "agentId": {
                          "description": "The agent id, when this side was resolved from this deployment.",
                          "type": "string"
                        },
                        "name": {
                          "description": "The agent name, when known.",
                          "type": "string"
                        },
                        "version": {
                          "description": "The spec version that was compared, when one was requested.",
                          "type": "number"
                        },
                        "spec": {
                          "description": "The normalized spec used in the comparison, with keys sorted for stable textual diffs.",
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {}
                        }
                      },
                      "required": [
                        "spec"
                      ],
                      "additionalProperties": false
                    },
                    "right": {
                      "type": "object",
                      "properties": {
                        "agentId": {
                          "description": "The agent id, when this side was resolved from this deployment.",
                          "type": "string"
                        },
                        "name": {
                          "description": "The agent name, when known.",
                          "type": "string"
                        },
                        "version": {
                          "description": "The spec version that was compared, when one was requested.",
                          "type": "number"
                        },
                        "spec": {
                          "description": "The normalized spec used in the comparison, with keys sorted for stable textual diffs.",
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {}
                        }
                      },
                      "required": [
                        "spec"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "identical",
                    "changes",
                    "left",
                    "right"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to a referenced agent",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A referenced agent was not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/builder/ask/": {
      "post": {
        "operationId": "askAgentBuilder",
        "summary": "Ask the AI agent builder and get the full reply",
        "tags": [
          "agents"
        ],
        "description": "Converse with Docana's agent-building expert without streaming: send one message, receive the complete reply. Use it to ask design questions (node types, transitions, platform gotchas) even when authoring a spec yourself, or to delegate the build — when the builder creates or edits a spec, the response carries the persisted artifact (id, version, spec) alongside the reply. On follow-up requests pass the returned `threadId` (to continue the conversation) and `artifact.id` as `artifactId` (so the builder edits that spec instead of creating a new one). Replies can take a minute or two for complex requests; clients that can consume a stream may prefer `runAgentBuilder`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "applicationId": {
                    "description": "Id of the application the builder run is scoped to.",
                    "examples": [
                      42
                    ],
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "message": {
                    "description": "Your message to the agent builder.",
                    "examples": [
                      "Which node type should gate a human handoff?"
                    ],
                    "type": "string",
                    "minLength": 1
                  },
                  "threadId": {
                    "description": "Thread id returned by a previous call, to continue that conversation. Omit to start fresh.",
                    "examples": [
                      "cmc5t2k9f0004l708d8yrn2q7"
                    ],
                    "type": "string",
                    "minLength": 1
                  },
                  "artifactId": {
                    "description": "Id of the agent-spec artifact a previous call returned (`artifact.id`). Pass it together with `threadId` on follow-up requests so the builder edits that artifact instead of creating a new one.",
                    "examples": [
                      "cmc5t3aa10009l708xyz12345"
                    ],
                    "type": "string",
                    "minLength": 1
                  }
                },
                "required": [
                  "applicationId",
                  "message"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The builder's reply and the conversation thread id.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "reply": {
                      "description": "The builder's full reply.",
                      "type": "string"
                    },
                    "threadId": {
                      "description": "Id of the conversation thread. Pass it on the next call to continue the conversation.",
                      "type": "string"
                    },
                    "artifact": {
                      "description": "Present when the builder created or edited an agent spec during this run: the persisted artifact's final state. Absent for advisory conversations that touch no spec.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "Id of the agent-spec artifact.",
                          "type": "string"
                        },
                        "version": {
                          "description": "Version the run produced.",
                          "type": "number"
                        },
                        "spec": {
                          "description": "The agent spec content the run left the artifact with."
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "reply"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid body.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller cannot open a builder conversation on that application.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "The builder run failed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/import/": {
      "post": {
        "operationId": "importAgents",
        "summary": "Import an agent bundle",
        "tags": [
          "agents"
        ],
        "description": "Imports an exported agent bundle (root agent plus sub-agents, evals, and routines) into an application. Use `createAgent` instead to create one new draft agent. The body is NOT a bare AgentSpec: to import a spec you authored, wrap it as `{ \"exportVersion\": 1, \"agent\": { \"name\": \"<name>\", \"spec\": <AgentSpec> } }`. Accepts `application/json` or `multipart/form-data` with a `file` field. Any supplied query `applicationId` must be a valid positive integer. When both valid body and query IDs are supplied, the body value wins.",
        "parameters": [
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Positive integer id of the application that scopes this operation.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "The exported agent bundle. Also accepted as `multipart/form-data` with the bundle JSON in a `file` field and an optional `applicationId` field. A top-level `applicationId` in the JSON payload is honored as well. Any supplied query `applicationId` must be a valid positive integer. When both valid body and query IDs are supplied, the body value wins.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "exportVersion": {
                    "type": "number",
                    "minimum": 1
                  },
                  "agent": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "sourceId": {
                        "description": "The id this entry had in the bundle, when `id` points at an agent that already exists in the target application. Stored as the imported agent's origin so a later import of the same bundle still recognizes it.",
                        "type": "string"
                      },
                      "name": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "description": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "spec": {
                        "type": "object",
                        "properties": {
                          "version": {
                            "description": "Schema version. Must be \"2.0\".",
                            "type": "string",
                            "const": "2.0"
                          },
                          "id": {
                            "description": "Unique identifier for this agent. Auto-generated if not provided.",
                            "type": "string"
                          },
                          "name": {
                            "description": "Human-readable name of the agent.",
                            "type": "string"
                          },
                          "prompt": {
                            "description": "System instructions for the agent. Can be a single string or an array of strings joined at runtime.",
                            "anyOf": [
                              {
                                "type": "string",
                                "minLength": 1
                              },
                              {
                                "minItems": 1,
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1
                                }
                              }
                            ]
                          },
                          "llm": {
                            "description": "LLM configuration for the router persona. Optional; uses platform defaults when omitted.",
                            "type": "object",
                            "properties": {
                              "provider": {
                                "description": "The LLM provider identifier (e.g., \"google\", \"openai\").",
                                "type": "string"
                              },
                              "model": {
                                "description": "The model name to use (e.g., \"gemini-2.0-flash\").",
                                "type": "string"
                              },
                              "temperature": {
                                "description": "Sampling temperature (0-2). IGNORED on Gemini 3.x models, which Google deprecated this parameter for on 2026-07-21 — it is accepted and silently discarded, so it no longer makes output more deterministic. Still accepted for older models and for backwards compatibility with existing specs.",
                                "type": "number"
                              },
                              "maxOutputTokens": {
                                "description": "Maximum number of tokens the model can generate.",
                                "type": "number"
                              },
                              "toolChoice": {
                                "description": "Controls how the model uses tools: auto (model decides), required (must use a tool), none (no tools).",
                                "type": "string",
                                "enum": [
                                  "auto",
                                  "required",
                                  "none"
                                ]
                              },
                              "jsonMode": {
                                "description": "If true, the model outputs valid JSON.",
                                "type": "boolean"
                              }
                            },
                            "required": [
                              "provider",
                              "model"
                            ]
                          },
                          "inlineEvaluationCriteria": {
                            "description": "Map of criteria ID to its full definition. Decision nodes reference these by key. These are criteria that have not been persisted to the database yet. During sandbox execution, they are loaded into memory. During publish, they are persisted to the database and this field is cleared.",
                            "type": "object",
                            "propertyNames": {
                              "type": "string"
                            },
                            "additionalProperties": {
                              "type": "object",
                              "properties": {
                                "name": {
                                  "description": "Human-readable name of this evaluation criteria. MUST be a non-empty short noun phrase (e.g. \"Real-Estate Availability Intent\"). Empty strings are forbidden.",
                                  "type": "string"
                                },
                                "type": {
                                  "description": "The evaluation criteria type (e.g., CUSTOM, QUALITY_HELPFULNESS).",
                                  "type": "string",
                                  "enum": [
                                    "QUALITY_ENGAGINGNESS",
                                    "QUALITY_COHERENCE",
                                    "QUALITY_CONSISTENCY",
                                    "QUALITY_FLUENCY",
                                    "QUALITY_RELEVANCE",
                                    "SECURITY_FINANCIAL_DETECTION",
                                    "SECURITY_PII_DETECTION",
                                    "SECURITY_ANOMALOUS_CONVERSATION",
                                    "PERSONALITY_EXTRAVERSION",
                                    "PERSONALITY_OPEN_TO_EXPERIENCE",
                                    "PERSONALITY_CONSCIENTIOUSNESS",
                                    "PERSONALITY_AGREEABLENESS",
                                    "PERSONALITY_NEUROTICISM",
                                    "PERSONALITY_OTHER",
                                    "DOCUMENT_INSIGHTS",
                                    "CUSTOM"
                                  ]
                                },
                                "evaluationCriteria": {
                                  "description": "REQUIRED non-empty instruction the evaluator follows to assess the input. One or two sentences in plain language: what to assess, and (if structuredDataParams is set) how to populate each declared field. Example: \"Decide whether the user is asking about real-estate availability. Set isAvailability to true only when the user is clearly asking whether a property is available; otherwise false.\" Empty strings, null, or omission make the reasoning useless and are forbidden.",
                                  "type": "string"
                                },
                                "evaluationSteps": {
                                  "description": "Ordered evaluation steps for the criteria.",
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "evaluationParams": {
                                  "description": "Parameters used during evaluation (e.g., INPUT, CONTEXT).",
                                  "type": "array",
                                  "items": {
                                    "type": "string",
                                    "enum": [
                                      "INPUT",
                                      "ACTUAL_OUTPUT",
                                      "EXPECTED_OUTPUT",
                                      "CONTEXT",
                                      "RETRIEVAL_CONTEXT",
                                      "EXECUTION_CONTEXT"
                                    ]
                                  }
                                },
                                "structuredDataParams": {
                                  "description": "Map of field name to a natural-language description of what to extract. The description should encode both the type and the legal values, e.g. \"true if the user is asking about real-estate availability, false otherwise\" (boolean), \"one of: AVAILABILITY, PRICING, CONTACT, OTHER\" (enum), or \"numeric score 1-5 reflecting urgency\" (number). Each declared field becomes a routing key accessible from transition conditions as \"evaluation.structuredData.<field>\" (and is also flattened into top-level vars for action templates). Prefer this for routing on what the user meant or asked; use scores.mean for confidence/quality routing.",
                                  "anyOf": [
                                    {
                                      "type": "object",
                                      "propertyNames": {
                                        "type": "string"
                                      },
                                      "additionalProperties": {}
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                },
                                "metadata": {
                                  "description": "Additional metadata for the criteria.",
                                  "anyOf": [
                                    {
                                      "type": "object",
                                      "propertyNames": {
                                        "type": "string"
                                      },
                                      "additionalProperties": {}
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                },
                                "enabled": {
                                  "description": "Whether this criteria is enabled. Defaults to true.",
                                  "type": "boolean"
                                }
                              },
                              "required": [
                                "name",
                                "type",
                                "evaluationCriteria"
                              ]
                            }
                          },
                          "workflow": {
                            "description": "The workflow definition including entry points and execution nodes.",
                            "type": "object",
                            "properties": {
                              "toolName": {
                                "description": "The tool name used to invoke this agent in the workflow.",
                                "type": "string"
                              },
                              "toolDescription": {
                                "description": "A description of what this agent does, shown to the LLM router.",
                                "type": "string"
                              },
                              "executionTimeoutSeconds": {
                                "description": "Wall-clock ceiling for ONE execution of this workflow, in seconds (30-1800). When the deadline passes the run is aborted — in-flight model calls are cancelled, sub-agents included — and the execution finishes with status TIMED_OUT, with the reason recorded on the nodes that were cut. Optional: an agent that declares nothing keeps the platform behavior (no explicit ceiling). Declare it when the agent legitimately runs for minutes (deep research, long tool chains) so a slow run is never mistaken for a hung one, or when it must never occupy a worker past a known bound. The budget is per attempt: a run resumed after a crash starts a fresh timer.",
                                "type": "integer",
                                "minimum": 30,
                                "maximum": 1800
                              },
                              "entryPoints": {
                                "description": "Entry points into the workflow. MUST contain at least one node ID; an empty array makes the workflow non-executable. When you restructure or rename the first node, update this list in the same operation so it points at the new entry node.",
                                "minItems": 1,
                                "type": "array",
                                "items": {
                                  "anyOf": [
                                    {
                                      "description": "Node ID to use as an unconditional entry point.",
                                      "type": "string"
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "nodeId": {
                                          "description": "The ID of the entry point node.",
                                          "type": "string"
                                        },
                                        "if": {
                                          "description": "Optional condition that must be met for this entry point to activate.",
                                          "$ref": "#/components/schemas/importAgents_schema0"
                                        }
                                      },
                                      "required": [
                                        "nodeId"
                                      ]
                                    }
                                  ]
                                }
                              },
                              "nodes": {
                                "description": "The workflow nodes: decision, action, subAgent, end, state, hub, jump, clearCache, javascript, or forEach.",
                                "type": "array",
                                "items": {
                                  "anyOf": [
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "decision"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this decision node.",
                                          "type": "string"
                                        },
                                        "evaluationCriteria": {
                                          "description": "Evaluation criteria IDs (string references) or inline criteria objects.",
                                          "type": "array",
                                          "items": {
                                            "anyOf": [
                                              {
                                                "type": "string"
                                              },
                                              {
                                                "type": "object",
                                                "properties": {
                                                  "id": {
                                                    "type": "string"
                                                  },
                                                  "name": {
                                                    "description": "Required non-empty short human-readable name for this criterion (e.g. \"Real-Estate Availability Intent\"). Never an empty string.",
                                                    "type": "string"
                                                  },
                                                  "type": {
                                                    "type": "string",
                                                    "enum": [
                                                      "QUALITY_ENGAGINGNESS",
                                                      "QUALITY_COHERENCE",
                                                      "QUALITY_CONSISTENCY",
                                                      "QUALITY_FLUENCY",
                                                      "QUALITY_RELEVANCE",
                                                      "SECURITY_FINANCIAL_DETECTION",
                                                      "SECURITY_PII_DETECTION",
                                                      "SECURITY_ANOMALOUS_CONVERSATION",
                                                      "PERSONALITY_EXTRAVERSION",
                                                      "PERSONALITY_OPEN_TO_EXPERIENCE",
                                                      "PERSONALITY_CONSCIENTIOUSNESS",
                                                      "PERSONALITY_AGREEABLENESS",
                                                      "PERSONALITY_NEUROTICISM",
                                                      "PERSONALITY_OTHER",
                                                      "DOCUMENT_INSIGHTS",
                                                      "CUSTOM"
                                                    ]
                                                  },
                                                  "evaluationCriteria": {
                                                    "description": "REQUIRED non-empty instruction telling the evaluator what to assess. One or two sentences in plain language: what to evaluate, and — when structuredDataParams is set — how to populate each declared field. Empty strings, null, or omission are forbidden; an empty description leaves the reasoning useless. Example: \"Decide whether the user is asking about real-estate availability. Set isAvailability to true only when the user is clearly asking whether a property is available; otherwise false.\"",
                                                    "type": "string"
                                                  },
                                                  "evaluationSteps": {
                                                    "type": "array",
                                                    "items": {
                                                      "type": "string"
                                                    }
                                                  },
                                                  "structuredDataParams": {
                                                    "anyOf": [
                                                      {
                                                        "type": "object",
                                                        "propertyNames": {
                                                          "type": "string"
                                                        },
                                                        "additionalProperties": {}
                                                      },
                                                      {
                                                        "type": "null"
                                                      }
                                                    ]
                                                  },
                                                  "metadata": {
                                                    "anyOf": [
                                                      {
                                                        "type": "object",
                                                        "propertyNames": {
                                                          "type": "string"
                                                        },
                                                        "additionalProperties": {}
                                                      },
                                                      {
                                                        "type": "null"
                                                      }
                                                    ]
                                                  },
                                                  "enabled": {
                                                    "type": "boolean"
                                                  },
                                                  "applicationId": {
                                                    "type": "number"
                                                  },
                                                  "evaluationParams": {
                                                    "type": "array",
                                                    "items": {
                                                      "type": "string",
                                                      "enum": [
                                                        "INPUT",
                                                        "ACTUAL_OUTPUT",
                                                        "EXPECTED_OUTPUT",
                                                        "CONTEXT",
                                                        "RETRIEVAL_CONTEXT",
                                                        "EXECUTION_CONTEXT"
                                                      ]
                                                    }
                                                  }
                                                },
                                                "required": [
                                                  "name",
                                                  "type",
                                                  "evaluationCriteria"
                                                ]
                                              }
                                            ]
                                          }
                                        },
                                        "transition": {
                                          "description": "Transitions to other nodes based on evaluation results.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/importAgents_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        },
                                        "cachePolicy": {
                                          "description": "Controls execution caching for this decision node across messages in a conversation. auto (default): cache result and use a lightweight guard evaluation to detect staleness. always: always use cached result until explicitly cleared. never: always re-evaluate all criteria every message (disables caching).",
                                          "type": "string",
                                          "enum": [
                                            "auto",
                                            "always",
                                            "never"
                                          ]
                                        },
                                        "selectionPolicy": {
                                          "description": "Controls which enabled criteria are evaluated each message. all (default): every enabled criterion runs. contextual: a lightweight router selects only the criteria relevant to the current input and conversation state; the rest are skipped. Skipped criteria are not evaluated, so their structuredData fields are absent downstream (route on them with the \"exists\"/\"notExists\" operators) and scores.mean reflects only the criteria that ran.",
                                          "type": "string",
                                          "enum": [
                                            "all",
                                            "contextual"
                                          ]
                                        },
                                        "alwaysRunCriteria": {
                                          "description": "Only used when selectionPolicy is \"contextual\": IDs of evaluation criteria that always run (they bypass the router); every other criterion is AI-selected per message. Use this to pin extractors whose structuredData a downstream node depends on. Ignored when selectionPolicy is \"all\".",
                                          "type": "array",
                                          "items": {
                                            "type": "string"
                                          }
                                        },
                                        "contextualSelectionPrompt": {
                                          "description": "Only used when selectionPolicy is \"contextual\": extra author guidance appended to the built-in router prompt to steer which criteria it picks (e.g. \"prefer running Consultar NFSe whenever the user mentions a nota fiscal, even indirectly\"). It augments the router — it does not replace its output contract or the safe fallback of running everything. Ignored when selectionPolicy is \"all\".",
                                          "type": "string"
                                        },
                                        "routingPolicy": {
                                          "description": "How many REASONINGS (criteria) may win the routing on this node per message. all (default): every matching conditional transition fires in parallel. bestReasoning: only the highest-scoring reasoning wins — ALL matched transitions whose condition is anchored on it fire (they are that reasoning's flow), everything anchored on other reasonings is suppressed. topReasonings: like bestReasoning but the best `maxReasonings` reasonings win. A matched transition is anchored on the highest-scoring criterion its condition references (via \"resultsById.<id>.score\" paths, at any nesting). Score ties between reasonings break by position in this node's evaluationCriteria list (earlier wins) — reorder the list to set priority. Matched transitions that reference NO criterion score (pure structuredData/context/state conditions) are outside the competition and always fire, like \"default\" and unconditional transitions. Criteria evaluation is unaffected — this arbitrates AFTER scoring, so it is the reliable way to get \"only one reasoning wins\" (independent per-criterion evaluations cannot be prompted into exclusivity).",
                                          "type": "string",
                                          "enum": [
                                            "all",
                                            "bestReasoning",
                                            "topReasonings"
                                          ]
                                        },
                                        "maxReasonings": {
                                          "description": "Only used when routingPolicy is \"topReasonings\": how many of the highest-scoring reasonings win the routing. Ignored for other policies (\"bestReasoning\" is exactly maxReasonings = 1).",
                                          "type": "integer",
                                          "minimum": 1,
                                          "maximum": 9007199254740991
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "evaluationCriteria",
                                        "transition"
                                      ]
                                    },
                                    {
                                      "oneOf": [
                                        {
                                          "type": "object",
                                          "properties": {
                                            "id": {
                                              "description": "Unique identifier for this node.",
                                              "type": "string"
                                            },
                                            "type": {
                                              "type": "string",
                                              "const": "action"
                                            },
                                            "label": {
                                              "description": "Human-readable label for this action node.",
                                              "type": "string"
                                            },
                                            "mode": {
                                              "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                              "type": "string",
                                              "enum": [
                                                "sync",
                                                "async"
                                              ]
                                            },
                                            "outputVar": {
                                              "description": "Variable name to store the action output for use by downstream nodes.",
                                              "type": "string"
                                            },
                                            "transition": {
                                              "description": "Transitions to other nodes after this action completes.",
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "if": {
                                                    "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                    "$ref": "#/components/schemas/importAgents_schema0"
                                                  },
                                                  "default": {
                                                    "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                    "type": "boolean"
                                                  },
                                                  "to": {
                                                    "type": "object",
                                                    "properties": {
                                                      "nodeId": {
                                                        "description": "The ID of the target node to transition to.",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "nodeId"
                                                    ]
                                                  },
                                                  "stop": {
                                                    "description": "If true, stop execution after this transition.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "to"
                                                ]
                                              }
                                            },
                                            "actionType": {
                                              "type": "string",
                                              "const": "INSTRUCTIONS"
                                            },
                                            "config": {
                                              "type": "object",
                                              "properties": {
                                                "instructions": {
                                                  "description": "The instructions for the LLM to execute.",
                                                  "type": "string"
                                                },
                                                "modelTier": {
                                                  "description": "The model tier to use for this instruction. Defaults to regular.",
                                                  "type": "string",
                                                  "enum": [
                                                    "lite",
                                                    "regular",
                                                    "pro"
                                                  ]
                                                },
                                                "thinkingEffortPct": {
                                                  "description": "Thinking effort percentage (0-100) controlling how much reasoning the model applies.",
                                                  "type": "number",
                                                  "minimum": 0,
                                                  "maximum": 100
                                                },
                                                "maxOutputTokens": {
                                                  "description": "Maximum tokens the model may generate for this node. On thinking models the budget is SHARED between reasoning and output — reasoning routinely consumes most of it — so a node whose structured output is truncated is usually better served by lowering thinkingEffortPct than by raising this. Defaults to the model maximum when omitted.",
                                                  "type": "integer",
                                                  "minimum": 1,
                                                  "maximum": 9007199254740991
                                                },
                                                "maxRetries": {
                                                  "description": "How many times this node retries a failed model call. Defaults to 2 when the node has an outputSchema and 5 otherwise. Raise it for nodes whose long outputs are exposed to dropped provider streams; it does not help failures the model reproduces deterministically.",
                                                  "type": "integer",
                                                  "minimum": 1,
                                                  "maximum": 10
                                                },
                                                "toolChoiceMode": {
                                                  "description": "Tool selection mode for this instruction. Defaults to auto when omitted.",
                                                  "type": "string",
                                                  "enum": [
                                                    "auto",
                                                    "none",
                                                    "tool",
                                                    "tools"
                                                  ]
                                                },
                                                "toolChoiceToolName": {
                                                  "description": "When toolChoiceMode is \"tool\", the specific tool name to force.",
                                                  "type": "string"
                                                },
                                                "toolChoiceToolNames": {
                                                  "description": "When toolChoiceMode is \"tools\", the list of allowed tool names.",
                                                  "type": "array",
                                                  "items": {
                                                    "type": "string"
                                                  }
                                                },
                                                "suppressTextResponse": {
                                                  "description": "When true, text output from the LLM is suppressed and only tool-call results are emitted. Useful when the instruction should only invoke tools (e.g., displayMedia) without generating follow-up text.",
                                                  "type": "boolean"
                                                },
                                                "stopAfterFirstToolCall": {
                                                  "description": "When true and a single tool is forced with text suppressed, the instruction stops after the first successful tool call. Defaults to false, which allows the tool to be called across multiple steps.",
                                                  "type": "boolean"
                                                },
                                                "internal": {
                                                  "description": "When true, this node is an intermediate step: its text/structured output is NOT shown to the user (not streamed, not persisted as a visible message part) and is only captured into the node's outputVar for downstream nodes. Reasoning and tool-call activity chips remain visible. Use for internal hand-offs (e.g. tool-driven data synthesis a later node consumes); the user-facing reply should come from a later, non-internal node.",
                                                  "type": "boolean"
                                                },
                                                "outputSchema": {
                                                  "description": "JSON Schema for structured output. When provided, the LLM will output valid JSON matching this schema instead of free-form text.",
                                                  "type": "object",
                                                  "properties": {
                                                    "type": {
                                                      "description": "JSON Schema type, must be \"object\" for structured output.",
                                                      "type": "string",
                                                      "const": "object"
                                                    },
                                                    "properties": {
                                                      "description": "Schema properties defining the expected output structure.",
                                                      "type": "object",
                                                      "propertyNames": {
                                                        "type": "string"
                                                      },
                                                      "additionalProperties": {}
                                                    },
                                                    "required": {
                                                      "description": "Array of required property names.",
                                                      "type": "array",
                                                      "items": {
                                                        "type": "string"
                                                      }
                                                    },
                                                    "additionalProperties": {
                                                      "description": "Whether to allow additional properties not defined in the schema.",
                                                      "type": "boolean"
                                                    },
                                                    "description": {
                                                      "description": "Description of the expected output to guide the LLM.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "type",
                                                    "properties"
                                                  ]
                                                },
                                                "grounding": {
                                                  "description": "Model-side grounding for this node. Only Google Search is available today.",
                                                  "type": "object",
                                                  "properties": {
                                                    "googleSearch": {
                                                      "description": "Enable Google Search grounding: the model searches the public web (via Gemini's built-in google_search tool) while executing this instruction and answers from what it finds. Set `{}` to enable with defaults. The node result then carries `grounding` — the queries Google ran and the sources it cited, each with the resolved article URL, its domain and the passages of the reply it supports — readable downstream as `nodes.<nodeId>.grounding` in javascript nodes and templates; the text/JSON reply itself still flows through outputVar as usual. With an outputSchema the search runs first and the JSON is synthesized afterwards with the numbered source list, so declare a `sourceIds` or `url` field if you want citations inside the structured output. Incompatible with toolChoiceMode \"tool\" and with suppressTextResponse (a forced tool call and Google Search in one request returns an empty reply); with toolChoiceMode \"none\" the node still searches but calls no other tool. Each prompt costs Google one search query per query the model decides to run (usually 4–10), billed per query beyond the project's free tier.",
                                                      "type": "object",
                                                      "properties": {
                                                        "excludeDomains": {
                                                          "description": "Domains Google Search must not ground on, e.g. [\"youtube.com\", \"reddit.com\"]. A domain excludes its subdomains too.",
                                                          "type": "array",
                                                          "items": {
                                                            "type": "string"
                                                          }
                                                        }
                                                      }
                                                    }
                                                  }
                                                },
                                                "urlContext": {
                                                  "description": "Gemini URL context: hand the model a list of URLs to READ IN FULL server-side instead of fetching their text into a variable first. The URLs come from the fixed \"urls\" list, from the \"from\" value path, or from both (fixed first). They are appended to the end of the instruction and the provider fetches and reads the pages inside the same call. With an outputSchema the node runs as a SINGLE call (reading and synthesis must share it), so pair it with toolChoiceMode \"none\" unless the node truly needs function tools. Limits: 20 URLs per call (extra ones are dropped and reported as `truncated`), public pages only — paywalls, Google News redirect links and private hosts fail. The model may skip fetching when the URLs sit inside a very long prompt, so prefer a dedicated short reading node over bolting URLs onto a large synthesis prompt. The node output carries `urlContext.{requested,retrieved,unread,truncated,invalid,unresolved,supported,tokens}`. `unread` is the integrity signal — it lists every URL the model did not read, including the ones dropped by the 20-URL cap — so branch on `nodes.<id>.urlContext.unread` for a fallback reader (inside a forEach body it holds only the last item). `unresolved` says the \"from\" path resolved to nothing, `invalid` lists entries that were not http(s) URLs, and `supported` is false when the model could not carry the tool: in those cases nothing was read at all. Retrieved page content is billed as input tokens and added to the node usage as `urlContextTokens`. Gemini 3+ models only.",
                                                  "type": "object",
                                                  "properties": {
                                                    "urls": {
                                                      "description": "Fixed http(s) URLs to read on every run, written out here — for pages that do not change per execution (a status page, a policy, a price list). Combine with \"from\" to read a fixed set plus whatever the run produced; the two lists concatenate, fixed URLs first.",
                                                      "type": "array",
                                                      "items": {
                                                        "type": "string"
                                                      }
                                                    },
                                                    "from": {
                                                      "description": "Dotted VALUE PATH (same resolution as forEach \"over\": workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — e.g. \"paraLer.soUrls\" or \"nodes.pick.result.urls\") to a URL list the run produced: an array of http(s) URL strings, a single URL string, or a JSON-encoded array string. Not a Handlebars template; a path wrapped in {{ }} is accepted and unwrapped.",
                                                      "type": "string",
                                                      "minLength": 1
                                                    }
                                                  }
                                                }
                                              },
                                              "required": [
                                                "instructions"
                                              ]
                                            }
                                          },
                                          "required": [
                                            "id",
                                            "type",
                                            "mode",
                                            "transition",
                                            "actionType",
                                            "config"
                                          ]
                                        },
                                        {
                                          "type": "object",
                                          "properties": {
                                            "id": {
                                              "description": "Unique identifier for this node.",
                                              "type": "string"
                                            },
                                            "type": {
                                              "type": "string",
                                              "const": "action"
                                            },
                                            "label": {
                                              "description": "Human-readable label for this action node.",
                                              "type": "string"
                                            },
                                            "mode": {
                                              "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                              "type": "string",
                                              "enum": [
                                                "sync",
                                                "async"
                                              ]
                                            },
                                            "outputVar": {
                                              "description": "Variable name to store the action output for use by downstream nodes.",
                                              "type": "string"
                                            },
                                            "transition": {
                                              "description": "Transitions to other nodes after this action completes.",
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "if": {
                                                    "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                    "$ref": "#/components/schemas/importAgents_schema0"
                                                  },
                                                  "default": {
                                                    "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                    "type": "boolean"
                                                  },
                                                  "to": {
                                                    "type": "object",
                                                    "properties": {
                                                      "nodeId": {
                                                        "description": "The ID of the target node to transition to.",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "nodeId"
                                                    ]
                                                  },
                                                  "stop": {
                                                    "description": "If true, stop execution after this transition.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "to"
                                                ]
                                              }
                                            },
                                            "actionType": {
                                              "type": "string",
                                              "const": "EMAIL"
                                            },
                                            "config": {
                                              "type": "object",
                                              "properties": {
                                                "to": {
                                                  "type": "string"
                                                },
                                                "senderType": {
                                                  "type": "string",
                                                  "enum": [
                                                    "default",
                                                    "gmail"
                                                  ]
                                                },
                                                "gmailIntegrationId": {
                                                  "type": "string"
                                                },
                                                "subject": {
                                                  "type": "string"
                                                },
                                                "body": {
                                                  "type": "string"
                                                },
                                                "cc": {
                                                  "type": "string"
                                                },
                                                "bcc": {
                                                  "type": "string"
                                                },
                                                "attachments": {
                                                  "type": "array",
                                                  "items": {
                                                    "type": "object",
                                                    "properties": {
                                                      "documentId": {
                                                        "type": "number"
                                                      },
                                                      "url": {
                                                        "type": "string"
                                                      },
                                                      "filename": {
                                                        "type": "string"
                                                      }
                                                    }
                                                  }
                                                },
                                                "templateId": {
                                                  "type": "string"
                                                },
                                                "templateName": {
                                                  "type": "string"
                                                },
                                                "applicationId": {
                                                  "type": "number"
                                                }
                                              },
                                              "required": [
                                                "to",
                                                "subject",
                                                "body"
                                              ]
                                            }
                                          },
                                          "required": [
                                            "id",
                                            "type",
                                            "mode",
                                            "transition",
                                            "actionType",
                                            "config"
                                          ]
                                        },
                                        {
                                          "type": "object",
                                          "properties": {
                                            "id": {
                                              "description": "Unique identifier for this node.",
                                              "type": "string"
                                            },
                                            "type": {
                                              "type": "string",
                                              "const": "action"
                                            },
                                            "label": {
                                              "description": "Human-readable label for this action node.",
                                              "type": "string"
                                            },
                                            "mode": {
                                              "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                              "type": "string",
                                              "enum": [
                                                "sync",
                                                "async"
                                              ]
                                            },
                                            "outputVar": {
                                              "description": "Variable name to store the action output for use by downstream nodes.",
                                              "type": "string"
                                            },
                                            "transition": {
                                              "description": "Transitions to other nodes after this action completes.",
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "if": {
                                                    "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                    "$ref": "#/components/schemas/importAgents_schema0"
                                                  },
                                                  "default": {
                                                    "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                    "type": "boolean"
                                                  },
                                                  "to": {
                                                    "type": "object",
                                                    "properties": {
                                                      "nodeId": {
                                                        "description": "The ID of the target node to transition to.",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "nodeId"
                                                    ]
                                                  },
                                                  "stop": {
                                                    "description": "If true, stop execution after this transition.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "to"
                                                ]
                                              }
                                            },
                                            "actionType": {
                                              "type": "string",
                                              "const": "WEBHOOK"
                                            },
                                            "config": {
                                              "type": "object",
                                              "properties": {
                                                "url": {
                                                  "type": "string"
                                                },
                                                "method": {
                                                  "type": "string",
                                                  "enum": [
                                                    "GET",
                                                    "POST",
                                                    "PUT",
                                                    "PATCH",
                                                    "DELETE"
                                                  ]
                                                },
                                                "headers": {
                                                  "type": "object",
                                                  "propertyNames": {
                                                    "type": "string"
                                                  },
                                                  "additionalProperties": {
                                                    "type": "string"
                                                  }
                                                },
                                                "queryParams": {
                                                  "type": "object",
                                                  "propertyNames": {
                                                    "type": "string"
                                                  },
                                                  "additionalProperties": {
                                                    "type": "string"
                                                  }
                                                },
                                                "body": {
                                                  "type": "string"
                                                },
                                                "timeout": {
                                                  "type": "number"
                                                },
                                                "responseMode": {
                                                  "description": "How to decode the response body. \"json\" (default): parse as JSON/text and expose via varsDelta. \"attachment\": read as binary bytes for multimodal input (e.g. PDFs, images).",
                                                  "type": "string",
                                                  "enum": [
                                                    "json",
                                                    "attachment"
                                                  ]
                                                },
                                                "asMessage": {
                                                  "description": "When true, append the response to the conversation as a new user message so downstream LLM nodes see it. In \"attachment\" mode the message carries a file content part; in \"json\" mode it carries the stringified body as text. Defaults to false — preserving the historical behavior where webhook responses only flow through varsDelta.",
                                                  "type": "boolean"
                                                },
                                                "suppressNoResponseFallback": {
                                                  "description": "Marks the webhook as a fire-and-forget trigger: the conversation is meant to end here, with the rest happening on the receiving system. When the call succeeds and the turn finishes without sending anything to the user, the channel skips its automatic \"sorry, something went wrong\" fallback message. A failed call (HTTP >= 400) still gets the fallback, since the user is then left waiting for nothing.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "url",
                                                "method"
                                              ]
                                            }
                                          },
                                          "required": [
                                            "id",
                                            "type",
                                            "mode",
                                            "transition",
                                            "actionType",
                                            "config"
                                          ]
                                        },
                                        {
                                          "type": "object",
                                          "properties": {
                                            "id": {
                                              "description": "Unique identifier for this node.",
                                              "type": "string"
                                            },
                                            "type": {
                                              "type": "string",
                                              "const": "action"
                                            },
                                            "label": {
                                              "description": "Human-readable label for this action node.",
                                              "type": "string"
                                            },
                                            "mode": {
                                              "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                              "type": "string",
                                              "enum": [
                                                "sync",
                                                "async"
                                              ]
                                            },
                                            "outputVar": {
                                              "description": "Variable name to store the action output for use by downstream nodes.",
                                              "type": "string"
                                            },
                                            "transition": {
                                              "description": "Transitions to other nodes after this action completes.",
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "if": {
                                                    "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                    "$ref": "#/components/schemas/importAgents_schema0"
                                                  },
                                                  "default": {
                                                    "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                    "type": "boolean"
                                                  },
                                                  "to": {
                                                    "type": "object",
                                                    "properties": {
                                                      "nodeId": {
                                                        "description": "The ID of the target node to transition to.",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "nodeId"
                                                    ]
                                                  },
                                                  "stop": {
                                                    "description": "If true, stop execution after this transition.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "to"
                                                ]
                                              }
                                            },
                                            "actionType": {
                                              "type": "string",
                                              "const": "DOCUMENT_TEMPLATE"
                                            },
                                            "config": {
                                              "type": "object",
                                              "properties": {
                                                "templateId": {
                                                  "type": "string"
                                                },
                                                "templateName": {
                                                  "type": "string"
                                                },
                                                "sendEmail": {
                                                  "type": "boolean"
                                                },
                                                "sendWhatsApp": {
                                                  "type": "boolean"
                                                },
                                                "recipientEmail": {
                                                  "type": "string"
                                                }
                                              },
                                              "required": [
                                                "templateId"
                                              ]
                                            }
                                          },
                                          "required": [
                                            "id",
                                            "type",
                                            "mode",
                                            "transition",
                                            "actionType",
                                            "config"
                                          ]
                                        },
                                        {
                                          "type": "object",
                                          "properties": {
                                            "id": {
                                              "description": "Unique identifier for this node.",
                                              "type": "string"
                                            },
                                            "type": {
                                              "type": "string",
                                              "const": "action"
                                            },
                                            "label": {
                                              "description": "Human-readable label for this action node.",
                                              "type": "string"
                                            },
                                            "mode": {
                                              "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                              "type": "string",
                                              "enum": [
                                                "sync",
                                                "async"
                                              ]
                                            },
                                            "outputVar": {
                                              "description": "Variable name to store the action output for use by downstream nodes.",
                                              "type": "string"
                                            },
                                            "transition": {
                                              "description": "Transitions to other nodes after this action completes.",
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "if": {
                                                    "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                    "$ref": "#/components/schemas/importAgents_schema0"
                                                  },
                                                  "default": {
                                                    "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                    "type": "boolean"
                                                  },
                                                  "to": {
                                                    "type": "object",
                                                    "properties": {
                                                      "nodeId": {
                                                        "description": "The ID of the target node to transition to.",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "nodeId"
                                                    ]
                                                  },
                                                  "stop": {
                                                    "description": "If true, stop execution after this transition.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "to"
                                                ]
                                              }
                                            },
                                            "actionType": {
                                              "type": "string",
                                              "const": "TOOL_CALL"
                                            },
                                            "config": {
                                              "type": "object",
                                              "properties": {
                                                "toolName": {
                                                  "description": "The name of the common tool to invoke.",
                                                  "type": "string"
                                                },
                                                "parameters": {
                                                  "description": "Per-parameter configuration. Keys are parameter names from the tool schema.",
                                                  "type": "object",
                                                  "propertyNames": {
                                                    "type": "string"
                                                  },
                                                  "additionalProperties": {
                                                    "type": "object",
                                                    "properties": {
                                                      "mode": {
                                                        "description": "Whether this parameter is hardcoded (static) or filled by the LLM at runtime (dynamic).",
                                                        "type": "string",
                                                        "enum": [
                                                          "static",
                                                          "dynamic"
                                                        ]
                                                      },
                                                      "staticValue": {
                                                        "description": "The fixed value for this parameter. Required when mode is \"static\"."
                                                      },
                                                      "instructions": {
                                                        "description": "Optional guidance for the LLM when filling this parameter (only used when mode is \"dynamic\").",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "mode"
                                                    ]
                                                  }
                                                },
                                                "instructions": {
                                                  "description": "General instructions for the LLM when resolving dynamic parameters.",
                                                  "type": "string"
                                                },
                                                "skipKnowledgeSearch": {
                                                  "description": "When a node has dynamic parameters, the model is normally forced to call similaritySearch first so parameter values are grounded in the knowledge base, costing one extra model round. Set true for tools that need no knowledge context (for example code execution) to call the configured tool directly. Ignored when every parameter is static, since no model runs at all.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "toolName"
                                              ]
                                            }
                                          },
                                          "required": [
                                            "id",
                                            "type",
                                            "mode",
                                            "transition",
                                            "actionType",
                                            "config"
                                          ]
                                        },
                                        {
                                          "type": "object",
                                          "properties": {
                                            "id": {
                                              "description": "Unique identifier for this node.",
                                              "type": "string"
                                            },
                                            "type": {
                                              "type": "string",
                                              "const": "action"
                                            },
                                            "label": {
                                              "description": "Human-readable label for this action node.",
                                              "type": "string"
                                            },
                                            "mode": {
                                              "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                              "type": "string",
                                              "enum": [
                                                "sync",
                                                "async"
                                              ]
                                            },
                                            "outputVar": {
                                              "description": "Variable name to store the action output for use by downstream nodes.",
                                              "type": "string"
                                            },
                                            "transition": {
                                              "description": "Transitions to other nodes after this action completes.",
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "if": {
                                                    "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                    "$ref": "#/components/schemas/importAgents_schema0"
                                                  },
                                                  "default": {
                                                    "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                    "type": "boolean"
                                                  },
                                                  "to": {
                                                    "type": "object",
                                                    "properties": {
                                                      "nodeId": {
                                                        "description": "The ID of the target node to transition to.",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "nodeId"
                                                    ]
                                                  },
                                                  "stop": {
                                                    "description": "If true, stop execution after this transition.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "to"
                                                ]
                                              }
                                            },
                                            "actionType": {
                                              "type": "string",
                                              "const": "FOLLOW_UP"
                                            },
                                            "config": {
                                              "type": "object",
                                              "properties": {
                                                "delayMinutes": {
                                                  "description": "Minutes to wait before checking whether to run the inner action. Common presets: 5, 10, 15. Maximum 1440 (24h). Cloud Scheduler is cron-based so the actual fire time is rounded to the next minute boundary.",
                                                  "type": "integer",
                                                  "minimum": 1,
                                                  "maximum": 1440
                                                },
                                                "cancelOnUserMessage": {
                                                  "description": "When true (default), skip the inner action if any USER message arrived after the node was reached. Set to false only if the follow-up should fire even after the user has replied.",
                                                  "type": "boolean"
                                                },
                                                "cancelOnAssistantMessage": {
                                                  "description": "When true (default), skip the inner action if any ASSISTANT text message was sent after the node was reached. Tool-only assistant messages (no text content) do NOT count. Prevents double-pinging when another node already produced a response.",
                                                  "type": "boolean"
                                                },
                                                "cancelOnArchive": {
                                                  "description": "When true (default), skip the inner action if the thread was archived between scheduling and firing.",
                                                  "type": "boolean"
                                                },
                                                "action": {
                                                  "description": "The inner action to run when the delay elapses and cancel rules pass. INSTRUCTIONS produces an LLM-generated text message (good for \"Are you still there?\"-style nudges). TOOL_CALL fires a display tool (good for offering options or showing media).",
                                                  "oneOf": [
                                                    {
                                                      "type": "object",
                                                      "properties": {
                                                        "actionType": {
                                                          "type": "string",
                                                          "const": "INSTRUCTIONS"
                                                        },
                                                        "config": {
                                                          "type": "object",
                                                          "properties": {
                                                            "instructions": {
                                                              "description": "The instructions for the LLM to execute.",
                                                              "type": "string"
                                                            },
                                                            "modelTier": {
                                                              "description": "The model tier to use for this instruction. Defaults to regular.",
                                                              "type": "string",
                                                              "enum": [
                                                                "lite",
                                                                "regular",
                                                                "pro"
                                                              ]
                                                            },
                                                            "thinkingEffortPct": {
                                                              "description": "Thinking effort percentage (0-100) controlling how much reasoning the model applies.",
                                                              "type": "number",
                                                              "minimum": 0,
                                                              "maximum": 100
                                                            },
                                                            "maxOutputTokens": {
                                                              "description": "Maximum tokens the model may generate for this node. On thinking models the budget is SHARED between reasoning and output — reasoning routinely consumes most of it — so a node whose structured output is truncated is usually better served by lowering thinkingEffortPct than by raising this. Defaults to the model maximum when omitted.",
                                                              "type": "integer",
                                                              "minimum": 1,
                                                              "maximum": 9007199254740991
                                                            },
                                                            "maxRetries": {
                                                              "description": "How many times this node retries a failed model call. Defaults to 2 when the node has an outputSchema and 5 otherwise. Raise it for nodes whose long outputs are exposed to dropped provider streams; it does not help failures the model reproduces deterministically.",
                                                              "type": "integer",
                                                              "minimum": 1,
                                                              "maximum": 10
                                                            },
                                                            "toolChoiceMode": {
                                                              "description": "Tool selection mode for this instruction. Defaults to auto when omitted.",
                                                              "type": "string",
                                                              "enum": [
                                                                "auto",
                                                                "none",
                                                                "tool",
                                                                "tools"
                                                              ]
                                                            },
                                                            "toolChoiceToolName": {
                                                              "description": "When toolChoiceMode is \"tool\", the specific tool name to force.",
                                                              "type": "string"
                                                            },
                                                            "toolChoiceToolNames": {
                                                              "description": "When toolChoiceMode is \"tools\", the list of allowed tool names.",
                                                              "type": "array",
                                                              "items": {
                                                                "type": "string"
                                                              }
                                                            },
                                                            "suppressTextResponse": {
                                                              "description": "When true, text output from the LLM is suppressed and only tool-call results are emitted. Useful when the instruction should only invoke tools (e.g., displayMedia) without generating follow-up text.",
                                                              "type": "boolean"
                                                            },
                                                            "stopAfterFirstToolCall": {
                                                              "description": "When true and a single tool is forced with text suppressed, the instruction stops after the first successful tool call. Defaults to false, which allows the tool to be called across multiple steps.",
                                                              "type": "boolean"
                                                            },
                                                            "internal": {
                                                              "description": "When true, this node is an intermediate step: its text/structured output is NOT shown to the user (not streamed, not persisted as a visible message part) and is only captured into the node's outputVar for downstream nodes. Reasoning and tool-call activity chips remain visible. Use for internal hand-offs (e.g. tool-driven data synthesis a later node consumes); the user-facing reply should come from a later, non-internal node.",
                                                              "type": "boolean"
                                                            },
                                                            "outputSchema": {
                                                              "description": "JSON Schema for structured output. When provided, the LLM will output valid JSON matching this schema instead of free-form text.",
                                                              "type": "object",
                                                              "properties": {
                                                                "type": {
                                                                  "description": "JSON Schema type, must be \"object\" for structured output.",
                                                                  "type": "string",
                                                                  "const": "object"
                                                                },
                                                                "properties": {
                                                                  "description": "Schema properties defining the expected output structure.",
                                                                  "type": "object",
                                                                  "propertyNames": {
                                                                    "type": "string"
                                                                  },
                                                                  "additionalProperties": {}
                                                                },
                                                                "required": {
                                                                  "description": "Array of required property names.",
                                                                  "type": "array",
                                                                  "items": {
                                                                    "type": "string"
                                                                  }
                                                                },
                                                                "additionalProperties": {
                                                                  "description": "Whether to allow additional properties not defined in the schema.",
                                                                  "type": "boolean"
                                                                },
                                                                "description": {
                                                                  "description": "Description of the expected output to guide the LLM.",
                                                                  "type": "string"
                                                                }
                                                              },
                                                              "required": [
                                                                "type",
                                                                "properties"
                                                              ]
                                                            },
                                                            "grounding": {
                                                              "description": "Model-side grounding for this node. Only Google Search is available today.",
                                                              "type": "object",
                                                              "properties": {
                                                                "googleSearch": {
                                                                  "description": "Enable Google Search grounding: the model searches the public web (via Gemini's built-in google_search tool) while executing this instruction and answers from what it finds. Set `{}` to enable with defaults. The node result then carries `grounding` — the queries Google ran and the sources it cited, each with the resolved article URL, its domain and the passages of the reply it supports — readable downstream as `nodes.<nodeId>.grounding` in javascript nodes and templates; the text/JSON reply itself still flows through outputVar as usual. With an outputSchema the search runs first and the JSON is synthesized afterwards with the numbered source list, so declare a `sourceIds` or `url` field if you want citations inside the structured output. Incompatible with toolChoiceMode \"tool\" and with suppressTextResponse (a forced tool call and Google Search in one request returns an empty reply); with toolChoiceMode \"none\" the node still searches but calls no other tool. Each prompt costs Google one search query per query the model decides to run (usually 4–10), billed per query beyond the project's free tier.",
                                                                  "type": "object",
                                                                  "properties": {
                                                                    "excludeDomains": {
                                                                      "description": "Domains Google Search must not ground on, e.g. [\"youtube.com\", \"reddit.com\"]. A domain excludes its subdomains too.",
                                                                      "type": "array",
                                                                      "items": {
                                                                        "type": "string"
                                                                      }
                                                                    }
                                                                  }
                                                                }
                                                              }
                                                            },
                                                            "urlContext": {
                                                              "description": "Gemini URL context: hand the model a list of URLs to READ IN FULL server-side instead of fetching their text into a variable first. The URLs come from the fixed \"urls\" list, from the \"from\" value path, or from both (fixed first). They are appended to the end of the instruction and the provider fetches and reads the pages inside the same call. With an outputSchema the node runs as a SINGLE call (reading and synthesis must share it), so pair it with toolChoiceMode \"none\" unless the node truly needs function tools. Limits: 20 URLs per call (extra ones are dropped and reported as `truncated`), public pages only — paywalls, Google News redirect links and private hosts fail. The model may skip fetching when the URLs sit inside a very long prompt, so prefer a dedicated short reading node over bolting URLs onto a large synthesis prompt. The node output carries `urlContext.{requested,retrieved,unread,truncated,invalid,unresolved,supported,tokens}`. `unread` is the integrity signal — it lists every URL the model did not read, including the ones dropped by the 20-URL cap — so branch on `nodes.<id>.urlContext.unread` for a fallback reader (inside a forEach body it holds only the last item). `unresolved` says the \"from\" path resolved to nothing, `invalid` lists entries that were not http(s) URLs, and `supported` is false when the model could not carry the tool: in those cases nothing was read at all. Retrieved page content is billed as input tokens and added to the node usage as `urlContextTokens`. Gemini 3+ models only.",
                                                              "type": "object",
                                                              "properties": {
                                                                "urls": {
                                                                  "description": "Fixed http(s) URLs to read on every run, written out here — for pages that do not change per execution (a status page, a policy, a price list). Combine with \"from\" to read a fixed set plus whatever the run produced; the two lists concatenate, fixed URLs first.",
                                                                  "type": "array",
                                                                  "items": {
                                                                    "type": "string"
                                                                  }
                                                                },
                                                                "from": {
                                                                  "description": "Dotted VALUE PATH (same resolution as forEach \"over\": workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — e.g. \"paraLer.soUrls\" or \"nodes.pick.result.urls\") to a URL list the run produced: an array of http(s) URL strings, a single URL string, or a JSON-encoded array string. Not a Handlebars template; a path wrapped in {{ }} is accepted and unwrapped.",
                                                                  "type": "string",
                                                                  "minLength": 1
                                                                }
                                                              }
                                                            }
                                                          },
                                                          "required": [
                                                            "instructions"
                                                          ]
                                                        }
                                                      },
                                                      "required": [
                                                        "actionType",
                                                        "config"
                                                      ]
                                                    },
                                                    {
                                                      "type": "object",
                                                      "properties": {
                                                        "actionType": {
                                                          "type": "string",
                                                          "const": "TOOL_CALL"
                                                        },
                                                        "config": {
                                                          "type": "object",
                                                          "properties": {
                                                            "toolName": {
                                                              "description": "The name of the common tool to invoke.",
                                                              "type": "string"
                                                            },
                                                            "parameters": {
                                                              "description": "Per-parameter configuration. Keys are parameter names from the tool schema.",
                                                              "type": "object",
                                                              "propertyNames": {
                                                                "type": "string"
                                                              },
                                                              "additionalProperties": {
                                                                "type": "object",
                                                                "properties": {
                                                                  "mode": {
                                                                    "description": "Whether this parameter is hardcoded (static) or filled by the LLM at runtime (dynamic).",
                                                                    "type": "string",
                                                                    "enum": [
                                                                      "static",
                                                                      "dynamic"
                                                                    ]
                                                                  },
                                                                  "staticValue": {
                                                                    "description": "The fixed value for this parameter. Required when mode is \"static\"."
                                                                  },
                                                                  "instructions": {
                                                                    "description": "Optional guidance for the LLM when filling this parameter (only used when mode is \"dynamic\").",
                                                                    "type": "string"
                                                                  }
                                                                },
                                                                "required": [
                                                                  "mode"
                                                                ]
                                                              }
                                                            },
                                                            "instructions": {
                                                              "description": "General instructions for the LLM when resolving dynamic parameters.",
                                                              "type": "string"
                                                            },
                                                            "skipKnowledgeSearch": {
                                                              "description": "When a node has dynamic parameters, the model is normally forced to call similaritySearch first so parameter values are grounded in the knowledge base, costing one extra model round. Set true for tools that need no knowledge context (for example code execution) to call the configured tool directly. Ignored when every parameter is static, since no model runs at all.",
                                                              "type": "boolean"
                                                            }
                                                          },
                                                          "required": [
                                                            "toolName"
                                                          ]
                                                        }
                                                      },
                                                      "required": [
                                                        "actionType",
                                                        "config"
                                                      ]
                                                    }
                                                  ]
                                                }
                                              },
                                              "required": [
                                                "delayMinutes",
                                                "action"
                                              ]
                                            }
                                          },
                                          "required": [
                                            "id",
                                            "type",
                                            "mode",
                                            "transition",
                                            "actionType",
                                            "config"
                                          ]
                                        }
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "subAgent"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this sub-agent node.",
                                          "type": "string"
                                        },
                                        "agentId": {
                                          "description": "The ID of the sub-agent to invoke.",
                                          "type": "string"
                                        },
                                        "instructions": {
                                          "description": "Optional instructions message prepended to the sub-agent conversation. Supports Handlebars interpolation against the parent execution scope: `{{var}}` reads workflow vars, `{{context.x}}` reads contextVars, `{{env.X}}` reads environment, `{{input.text}}` reads the original user input, and `{{nodes.<id>.<path>}}` reads prior node outputs.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Optional transitions to continue the flow after the sub-agent returns.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/importAgents_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "agentId"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "end"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this end node.",
                                          "type": "string"
                                        },
                                        "config": {
                                          "description": "Optional configuration for the end node behavior.",
                                          "type": "object",
                                          "properties": {
                                            "resetConversationHistory": {
                                              "description": "If true, the next user message starts a new conversation with no prior history.",
                                              "type": "boolean"
                                            }
                                          }
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "state"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this state node.",
                                          "type": "string"
                                        },
                                        "outputVar": {
                                          "description": "Agent-scope get only: variable name that receives the value stored under `config.key` (null when the key has never been written). Downstream templates read it as `{{<outputVar>}}`; transition conditions as `{source:\"vars\", path:\"<outputVar>...\"}`.",
                                          "type": "string"
                                        },
                                        "config": {
                                          "type": "object",
                                          "properties": {
                                            "scope": {
                                              "description": "How long the data lives and who sees it. execution: this run only. session: this conversation (thread) — a NEW conversation starts empty. agent: durable memory shared by every execution of this agent, across conversations — use it to remember things between independent runs. Survives clearCache.",
                                              "type": "string",
                                              "enum": [
                                                "execution",
                                                "session",
                                                "agent"
                                              ]
                                            },
                                            "operation": {
                                              "description": "Agent scope only (default set). set: durably store the `state` entries. get: read the entry under `key` into `outputVar`. Execution/session scopes are always set — their values are injected into templates automatically, so no get is needed.",
                                              "type": "string",
                                              "enum": [
                                                "set",
                                                "get"
                                              ]
                                            },
                                            "key": {
                                              "description": "Agent-scope get: the memory key to read. Supports Handlebars (e.g. \"evidence-{{context.cnpj}}\") so one node can address per-entity entries. Rendered keys are limited to 512 characters.",
                                              "type": "string"
                                            },
                                            "state": {
                                              "description": "Key-value pairs to set (required for set operations). String values support Handlebars. In agent scope the KEYS are templates too (e.g. \"evidence-{{context.cnpj}}\"), each entry is stored as its own durable row, and serialized values are size-capped.",
                                              "type": "object",
                                              "propertyNames": {
                                                "type": "string"
                                              },
                                              "additionalProperties": {}
                                            }
                                          },
                                          "required": [
                                            "scope"
                                          ]
                                        },
                                        "transition": {
                                          "description": "Optional transitions to continue the flow after setting state.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/importAgents_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "config"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "hub"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this hub node.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Transitions to route connections to other nodes.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/importAgents_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "jump"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this jump node.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Target node to jump to unconditionally.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/importAgents_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "clearCache"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this clear cache node.",
                                          "type": "string"
                                        },
                                        "config": {
                                          "description": "Optional configuration controlling what is cleared.",
                                          "type": "object",
                                          "properties": {
                                            "clearScope": {
                                              "description": "What to clear. executionCache (default): clears only the decision result cache. all: clears the entire session state including user-defined session variables.",
                                              "type": "string",
                                              "enum": [
                                                "executionCache",
                                                "all"
                                              ]
                                            }
                                          }
                                        },
                                        "transition": {
                                          "description": "Optional transitions to continue the flow after clearing cache.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/importAgents_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "javascript"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this JavaScript node.",
                                          "type": "string"
                                        },
                                        "outputVar": {
                                          "description": "Variable name to store the returned value for downstream nodes. Downstream templates read it as `{{<outputVar>}}`; transition conditions as `{source:\"vars\", path:\"<outputVar>...\"}`.",
                                          "type": "string"
                                        },
                                        "config": {
                                          "type": "object",
                                          "properties": {
                                            "code": {
                                              "description": "JavaScript source executed in a sandboxed QuickJS interpreter. Written as a function body: it receives ({ vars, evaluation, context, env, input, nodes }) and must `return` a JSON-serializable value. Synchronous only — no network, filesystem, require/import, or timers.",
                                              "type": "string"
                                            },
                                            "timeoutMs": {
                                              "description": "CPU deadline in milliseconds. Default 1000, max 10000.",
                                              "type": "integer",
                                              "minimum": 1,
                                              "maximum": 10000
                                            }
                                          },
                                          "required": [
                                            "code"
                                          ]
                                        },
                                        "transition": {
                                          "description": "Optional transitions to continue the flow after the code runs.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/importAgents_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "config"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "forEach"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this forEach node.",
                                          "type": "string"
                                        },
                                        "over": {
                                          "description": "Dotted path to the array to iterate, resolved against the execution scope: top-level workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — for example \"research.socioAlvos\" or \"nodes.build_plan.result.targets\". This is a VALUE PATH, not a Handlebars template: Handlebars renders to a string, so an array passed through it would arrive as \"[object Object]\". A path wrapped in {{ }} is accepted and unwrapped. If the path does not resolve to an array the node fails loudly instead of iterating a string.",
                                          "type": "string"
                                        },
                                        "as": {
                                          "description": "Variable name bound to the current element inside the body node: \"socio\" makes {{socio.nome}} available to the body's templates. Must not be \"iteration\", which is reserved for the {index, total} binding also exposed to the body.",
                                          "type": "string"
                                        },
                                        "each": {
                                          "description": "The body node, referenced by ID. Must be an action, javascript or subAgent node declared in workflow.nodes with no other incoming transitions, and must not be an entry point. Its own \"transition\" array is ignored — the forEach node owns what happens after every item finishes. decision nodes are rejected because the execution cache is keyed by node ID, so parallel instances would contend for one cache entry.",
                                          "type": "object",
                                          "properties": {
                                            "nodeId": {
                                              "description": "The ID of the node to run once per item.",
                                              "type": "string"
                                            }
                                          },
                                          "required": [
                                            "nodeId"
                                          ]
                                        },
                                        "collectInto": {
                                          "description": "Variable name receiving the per-item results array. Each entry is {index, item, ok, value?, grounding?, error?, errorName?}, where \"value\" is whatever the body node's own outputVar would have held (undefined when the body declares none) and \"grounding\" is that item's Google Search queries and sources when the body is a grounded INSTRUCTIONS node — the same shape a standalone node exposes as nodes.<id>.grounding. Entries stay aligned with the source array by index, including failed items, so a downstream node can tell \"this item returned nothing\" apart from \"this item was never tried\". Omit only if nothing downstream needs the results.",
                                          "type": "string"
                                        },
                                        "maxConcurrency": {
                                          "description": "How many items run at once. Defaults to 5. Raise carefully: per-item parallelism hits provider rate limits well before it hits platform limits.",
                                          "type": "integer",
                                          "minimum": 1,
                                          "maximum": 20
                                        },
                                        "transition": {
                                          "description": "Transitions to continue the flow after every item has finished.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/importAgents_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "over",
                                        "as",
                                        "each"
                                      ]
                                    }
                                  ]
                                }
                              }
                            },
                            "required": [
                              "toolName",
                              "toolDescription",
                              "entryPoints",
                              "nodes"
                            ]
                          },
                          "tools": {
                            "deprecated": true,
                            "description": "Deprecated and ignored. Tool availability is configured by the application, not the agent spec.",
                            "type": "array",
                            "items": {}
                          },
                          "metadata": {
                            "description": "Arbitrary metadata for custom extensions. Not used by the execution engine.",
                            "type": "object",
                            "propertyNames": {
                              "type": "string"
                            },
                            "additionalProperties": {}
                          }
                        },
                        "required": [
                          "version",
                          "name",
                          "prompt",
                          "workflow"
                        ]
                      },
                      "evals": {
                        "default": [],
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "name": {
                              "type": "string",
                              "minLength": 1
                            },
                            "description": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "scheduler": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "evalSpec": {},
                            "enabled": {
                              "type": "boolean"
                            },
                            "selfImproveEnabled": {
                              "type": "boolean"
                            },
                            "selfImproveTargetScore": {
                              "anyOf": [
                                {
                                  "type": "number"
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "selfImproveMaxIterations": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            "folderPath": {
                              "description": "Materialized '/'-separated folder path of the eval (e.g. 'Regressão/Checkout'), or null for root.",
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "tags": {
                              "description": "Free-form labels of the eval.",
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "metadata": {
                              "description": "Free-form data of the eval, including the `sources` conversations it was built from.",
                              "anyOf": [
                                {
                                  "description": "Free-form data recorded on the eval. Provenance belongs under `sources`, a list whose entries have documented keys so every writer points at the originating conversations the same way. An eval drawn from a single conversation carries a one-element list.",
                                  "type": "object",
                                  "properties": {
                                    "sources": {
                                      "description": "The conversations the eval was built from, most relevant first.",
                                      "maxItems": 25,
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "threadId": {
                                            "description": "Id of the thread the eval was built from.",
                                            "examples": [
                                              "cmc3k5r2b0004l608w1t8fmz9"
                                            ],
                                            "type": "string",
                                            "minLength": 1,
                                            "maxLength": 255
                                          },
                                          "executionId": {
                                            "description": "Id of the agent execution the eval was built from.",
                                            "examples": [
                                              "exec_01j9z3k2b4c5"
                                            ],
                                            "type": "string",
                                            "minLength": 1,
                                            "maxLength": 255
                                          },
                                          "messageId": {
                                            "description": "Id of the specific message the eval was built from.",
                                            "examples": [
                                              "cmc3k9p7f0007"
                                            ],
                                            "type": "string",
                                            "minLength": 1,
                                            "maxLength": 255
                                          },
                                          "url": {
                                            "description": "Link to the source conversation. Must be an absolute http(s) URL.",
                                            "examples": [
                                              "https://platform.docana.com/application/42/agents/a1/logs?search=thread-1"
                                            ],
                                            "type": "string",
                                            "minLength": 1,
                                            "maxLength": 2048
                                          },
                                          "label": {
                                            "description": "Human friendly name of the source conversation.",
                                            "examples": [
                                              "WhatsApp 5511 — 12/08"
                                            ],
                                            "type": "string",
                                            "minLength": 1,
                                            "maxLength": 255
                                          },
                                          "capturedAt": {
                                            "description": "ISO 8601 timestamp of when the eval was captured.",
                                            "examples": [
                                              "2026-08-17T12:00:00.000Z"
                                            ],
                                            "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))$"
                                          }
                                        },
                                        "additionalProperties": {}
                                      }
                                    }
                                  },
                                  "additionalProperties": {}
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            }
                          },
                          "required": [
                            "name",
                            "evalSpec"
                          ]
                        }
                      },
                      "routines": {
                        "default": [],
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "name": {
                              "type": "string",
                              "minLength": 1
                            },
                            "prompt": {
                              "type": "string"
                            },
                            "enabled": {
                              "default": true,
                              "type": "boolean"
                            },
                            "metadata": {
                              "anyOf": [
                                {
                                  "type": "object",
                                  "propertyNames": {
                                    "type": "string"
                                  },
                                  "additionalProperties": {}
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "triggers": {
                              "default": [],
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "enum": [
                                      "SCHEDULED",
                                      "API",
                                      "DOCUMENT_EVENT"
                                    ]
                                  },
                                  "enabled": {
                                    "default": true,
                                    "type": "boolean"
                                  },
                                  "cronExpression": {
                                    "anyOf": [
                                      {
                                        "type": "string"
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ]
                                  },
                                  "collectionIds": {
                                    "default": [],
                                    "type": "array",
                                    "items": {
                                      "type": "integer",
                                      "minimum": -9007199254740991,
                                      "maximum": 9007199254740991
                                    }
                                  },
                                  "eventName": {
                                    "anyOf": [
                                      {
                                        "type": "string"
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ]
                                  },
                                  "metadata": {
                                    "type": "object",
                                    "propertyNames": {
                                      "type": "string"
                                    },
                                    "additionalProperties": {}
                                  }
                                },
                                "required": [
                                  "type"
                                ]
                              }
                            }
                          },
                          "required": [
                            "name",
                            "prompt"
                          ]
                        }
                      },
                      "insights": {
                        "anyOf": [
                          {
                            "type": "object",
                            "properties": {
                              "enabled": {
                                "description": "Master kill switch for this agent's insights. When false, no extraction runs anywhere (the post-execution hook is suppressed and the archive API rejects summarize=true) and no prior insights are injected into new conversations.",
                                "type": "boolean"
                              },
                              "shareWithPastConversations": {
                                "description": "When true (and `enabled` is true), inject summaries from this user's past archived conversations in the same application into LLM calls that consume conversation history (instruction nodes; decision criteria with EvaluationParams.CONTEXT). Defaults to false.",
                                "type": "boolean"
                              },
                              "summaryMode": {
                                "description": "When to extract insights for this agent. \"afterExecution\" (default) runs archive + extraction after every successful agent turn (with or without an End node), so channels like WhatsApp keep producing insights. \"onArchive\" skips the automatic hook; insights are only extracted when the archive API is called with summarize=true.",
                                "type": "string",
                                "enum": [
                                  "afterExecution",
                                  "onArchive"
                                ]
                              },
                              "summaryConfig": {
                                "description": "Config used when this agent extracts a new summary (End-node generateInsights or archive API with summarize=true).",
                                "type": "object",
                                "properties": {
                                  "summaryLength": {
                                    "description": "Target length of the generated summary.",
                                    "type": "string",
                                    "enum": [
                                      "short",
                                      "medium",
                                      "detailed"
                                    ]
                                  },
                                  "customPrompt": {
                                    "description": "Optional extra guidance appended to the summarizer system prompt.",
                                    "type": "string"
                                  },
                                  "historyMessageLimit": {
                                    "description": "Cap on the number of recent messages included when generating the summary. Omitted = no cap.",
                                    "type": "integer",
                                    "exclusiveMinimum": 0,
                                    "maximum": 9007199254740991
                                  },
                                  "maxSummaryChars": {
                                    "description": "Optional cap on the persisted summary length (characters).",
                                    "type": "integer",
                                    "exclusiveMinimum": 0,
                                    "maximum": 9007199254740991
                                  }
                                }
                              },
                              "frequency": {
                                "description": "How often insights are extracted. \"onEnd\" (default) extracts once when the conversation is archived. \"everyTurn\" extracts after every message — the legacy behaviour, which costs roughly O(N^2) tokens over an N-turn conversation. When absent, the legacy `summaryMode` is used: \"afterExecution\" maps to \"everyTurn\", anything else maps to \"onEnd\". Any other stored value (e.g. a removed legacy mode) resolves to \"onEnd\", the cheap option.",
                                "type": "string",
                                "enum": [
                                  "onEnd",
                                  "everyTurn"
                                ]
                              },
                              "samplingRate": {
                                "description": "Share of conversations that produce insights automatically, 0..1. Defaults to 1 (all). The decision is a deterministic hash of (agentId, threadId), so a conversation is either sampled for its whole life or not at all. Explicit archive calls and on-demand generation always run regardless of this rate.",
                                "type": "number",
                                "minimum": 0,
                                "maximum": 1
                              },
                              "dataPoints": {
                                "description": "Structured data points to extract from the conversation when generating insights.",
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Stable identifier for the data point; reused across saves so snapshot history and aggregations stay correlated over time.",
                                      "type": "string"
                                    },
                                    "name": {
                                      "description": "Human-readable name of the data point (displayed in the UI).",
                                      "type": "string"
                                    },
                                    "description": {
                                      "description": "Instruction describing what this data point should capture from the conversation.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "description": "The expected type of the extracted value.",
                                      "type": "string",
                                      "enum": [
                                        "string",
                                        "number",
                                        "boolean"
                                      ]
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "name",
                                    "description",
                                    "type"
                                  ]
                                }
                              }
                            },
                            "required": [
                              "enabled"
                            ]
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "evalMockBaseline": {
                        "anyOf": [
                          {
                            "type": "object",
                            "propertyNames": {
                              "type": "string"
                            },
                            "additionalProperties": {
                              "anyOf": [
                                {
                                  "type": "object",
                                  "properties": {
                                    "type": {
                                      "examples": [
                                        "webhook"
                                      ],
                                      "type": "string",
                                      "const": "webhook"
                                    },
                                    "mode": {
                                      "default": "staticResponse",
                                      "type": "string",
                                      "const": "staticResponse"
                                    },
                                    "response": {
                                      "anyOf": [
                                        {
                                          "type": "object",
                                          "properties": {
                                            "status": {
                                              "examples": [
                                                200
                                              ],
                                              "type": "integer",
                                              "minimum": 100,
                                              "maximum": 599
                                            },
                                            "headers": {
                                              "examples": [
                                                {
                                                  "content-type": "application/json"
                                                }
                                              ],
                                              "type": "object",
                                              "propertyNames": {
                                                "type": "string"
                                              },
                                              "additionalProperties": {
                                                "type": "string"
                                              }
                                            },
                                            "body": {
                                              "examples": [
                                                {
                                                  "orderStatus": "shipped"
                                                }
                                              ],
                                              "$ref": "#/components/schemas/importAgents_schema1"
                                            },
                                            "noResponse": {
                                              "not": {}
                                            }
                                          },
                                          "required": [
                                            "status"
                                          ]
                                        },
                                        {
                                          "type": "object",
                                          "properties": {
                                            "noResponse": {
                                              "examples": [
                                                true
                                              ],
                                              "type": "boolean",
                                              "const": true
                                            },
                                            "error": {
                                              "examples": [
                                                "connect ECONNREFUSED 10.0.0.4:443"
                                              ],
                                              "type": "string"
                                            },
                                            "status": {
                                              "not": {}
                                            }
                                          },
                                          "required": [
                                            "noResponse"
                                          ]
                                        }
                                      ]
                                    }
                                  },
                                  "required": [
                                    "type",
                                    "response"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "type": {
                                      "examples": [
                                        "webhook"
                                      ],
                                      "type": "string",
                                      "const": "webhook"
                                    },
                                    "mode": {
                                      "type": "string",
                                      "const": "sequence"
                                    },
                                    "responses": {
                                      "examples": [
                                        [
                                          {
                                            "status": 400,
                                            "body": {
                                              "error": "CEP inválido"
                                            }
                                          },
                                          {
                                            "status": 201,
                                            "body": {
                                              "data": {
                                                "status": "AUTORIZADA"
                                              }
                                            }
                                          }
                                        ]
                                      ],
                                      "minItems": 1,
                                      "type": "array",
                                      "items": {
                                        "anyOf": [
                                          {
                                            "type": "object",
                                            "properties": {
                                              "status": {
                                                "examples": [
                                                  200
                                                ],
                                                "type": "integer",
                                                "minimum": 100,
                                                "maximum": 599
                                              },
                                              "headers": {
                                                "examples": [
                                                  {
                                                    "content-type": "application/json"
                                                  }
                                                ],
                                                "type": "object",
                                                "propertyNames": {
                                                  "type": "string"
                                                },
                                                "additionalProperties": {
                                                  "type": "string"
                                                }
                                              },
                                              "body": {
                                                "examples": [
                                                  {
                                                    "orderStatus": "shipped"
                                                  }
                                                ],
                                                "$ref": "#/components/schemas/importAgents_schema1"
                                              },
                                              "noResponse": {
                                                "not": {}
                                              }
                                            },
                                            "required": [
                                              "status"
                                            ]
                                          },
                                          {
                                            "type": "object",
                                            "properties": {
                                              "noResponse": {
                                                "examples": [
                                                  true
                                                ],
                                                "type": "boolean",
                                                "const": true
                                              },
                                              "error": {
                                                "examples": [
                                                  "connect ECONNREFUSED 10.0.0.4:443"
                                                ],
                                                "type": "string"
                                              },
                                              "status": {
                                                "not": {}
                                              }
                                            },
                                            "required": [
                                              "noResponse"
                                            ]
                                          }
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "type",
                                    "mode",
                                    "responses"
                                  ]
                                }
                              ]
                            }
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "required": [
                      "spec"
                    ]
                  },
                  "subAgents": {
                    "default": [],
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "sourceId": {
                          "description": "The id this entry had in the bundle, when `id` points at an agent that already exists in the target application. Stored as the imported agent's origin so a later import of the same bundle still recognizes it.",
                          "type": "string"
                        },
                        "name": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "description": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "spec": {
                          "type": "object",
                          "properties": {
                            "version": {
                              "description": "Schema version. Must be \"2.0\".",
                              "type": "string",
                              "const": "2.0"
                            },
                            "id": {
                              "description": "Unique identifier for this agent. Auto-generated if not provided.",
                              "type": "string"
                            },
                            "name": {
                              "description": "Human-readable name of the agent.",
                              "type": "string"
                            },
                            "prompt": {
                              "description": "System instructions for the agent. Can be a single string or an array of strings joined at runtime.",
                              "anyOf": [
                                {
                                  "type": "string",
                                  "minLength": 1
                                },
                                {
                                  "minItems": 1,
                                  "type": "array",
                                  "items": {
                                    "type": "string",
                                    "minLength": 1
                                  }
                                }
                              ]
                            },
                            "llm": {
                              "description": "LLM configuration for the router persona. Optional; uses platform defaults when omitted.",
                              "type": "object",
                              "properties": {
                                "provider": {
                                  "description": "The LLM provider identifier (e.g., \"google\", \"openai\").",
                                  "type": "string"
                                },
                                "model": {
                                  "description": "The model name to use (e.g., \"gemini-2.0-flash\").",
                                  "type": "string"
                                },
                                "temperature": {
                                  "description": "Sampling temperature (0-2). IGNORED on Gemini 3.x models, which Google deprecated this parameter for on 2026-07-21 — it is accepted and silently discarded, so it no longer makes output more deterministic. Still accepted for older models and for backwards compatibility with existing specs.",
                                  "type": "number"
                                },
                                "maxOutputTokens": {
                                  "description": "Maximum number of tokens the model can generate.",
                                  "type": "number"
                                },
                                "toolChoice": {
                                  "description": "Controls how the model uses tools: auto (model decides), required (must use a tool), none (no tools).",
                                  "type": "string",
                                  "enum": [
                                    "auto",
                                    "required",
                                    "none"
                                  ]
                                },
                                "jsonMode": {
                                  "description": "If true, the model outputs valid JSON.",
                                  "type": "boolean"
                                }
                              },
                              "required": [
                                "provider",
                                "model"
                              ]
                            },
                            "inlineEvaluationCriteria": {
                              "description": "Map of criteria ID to its full definition. Decision nodes reference these by key. These are criteria that have not been persisted to the database yet. During sandbox execution, they are loaded into memory. During publish, they are persisted to the database and this field is cleared.",
                              "type": "object",
                              "propertyNames": {
                                "type": "string"
                              },
                              "additionalProperties": {
                                "type": "object",
                                "properties": {
                                  "name": {
                                    "description": "Human-readable name of this evaluation criteria. MUST be a non-empty short noun phrase (e.g. \"Real-Estate Availability Intent\"). Empty strings are forbidden.",
                                    "type": "string"
                                  },
                                  "type": {
                                    "description": "The evaluation criteria type (e.g., CUSTOM, QUALITY_HELPFULNESS).",
                                    "type": "string",
                                    "enum": [
                                      "QUALITY_ENGAGINGNESS",
                                      "QUALITY_COHERENCE",
                                      "QUALITY_CONSISTENCY",
                                      "QUALITY_FLUENCY",
                                      "QUALITY_RELEVANCE",
                                      "SECURITY_FINANCIAL_DETECTION",
                                      "SECURITY_PII_DETECTION",
                                      "SECURITY_ANOMALOUS_CONVERSATION",
                                      "PERSONALITY_EXTRAVERSION",
                                      "PERSONALITY_OPEN_TO_EXPERIENCE",
                                      "PERSONALITY_CONSCIENTIOUSNESS",
                                      "PERSONALITY_AGREEABLENESS",
                                      "PERSONALITY_NEUROTICISM",
                                      "PERSONALITY_OTHER",
                                      "DOCUMENT_INSIGHTS",
                                      "CUSTOM"
                                    ]
                                  },
                                  "evaluationCriteria": {
                                    "description": "REQUIRED non-empty instruction the evaluator follows to assess the input. One or two sentences in plain language: what to assess, and (if structuredDataParams is set) how to populate each declared field. Example: \"Decide whether the user is asking about real-estate availability. Set isAvailability to true only when the user is clearly asking whether a property is available; otherwise false.\" Empty strings, null, or omission make the reasoning useless and are forbidden.",
                                    "type": "string"
                                  },
                                  "evaluationSteps": {
                                    "description": "Ordered evaluation steps for the criteria.",
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "evaluationParams": {
                                    "description": "Parameters used during evaluation (e.g., INPUT, CONTEXT).",
                                    "type": "array",
                                    "items": {
                                      "type": "string",
                                      "enum": [
                                        "INPUT",
                                        "ACTUAL_OUTPUT",
                                        "EXPECTED_OUTPUT",
                                        "CONTEXT",
                                        "RETRIEVAL_CONTEXT",
                                        "EXECUTION_CONTEXT"
                                      ]
                                    }
                                  },
                                  "structuredDataParams": {
                                    "description": "Map of field name to a natural-language description of what to extract. The description should encode both the type and the legal values, e.g. \"true if the user is asking about real-estate availability, false otherwise\" (boolean), \"one of: AVAILABILITY, PRICING, CONTACT, OTHER\" (enum), or \"numeric score 1-5 reflecting urgency\" (number). Each declared field becomes a routing key accessible from transition conditions as \"evaluation.structuredData.<field>\" (and is also flattened into top-level vars for action templates). Prefer this for routing on what the user meant or asked; use scores.mean for confidence/quality routing.",
                                    "anyOf": [
                                      {
                                        "type": "object",
                                        "propertyNames": {
                                          "type": "string"
                                        },
                                        "additionalProperties": {}
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ]
                                  },
                                  "metadata": {
                                    "description": "Additional metadata for the criteria.",
                                    "anyOf": [
                                      {
                                        "type": "object",
                                        "propertyNames": {
                                          "type": "string"
                                        },
                                        "additionalProperties": {}
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ]
                                  },
                                  "enabled": {
                                    "description": "Whether this criteria is enabled. Defaults to true.",
                                    "type": "boolean"
                                  }
                                },
                                "required": [
                                  "name",
                                  "type",
                                  "evaluationCriteria"
                                ]
                              }
                            },
                            "workflow": {
                              "description": "The workflow definition including entry points and execution nodes.",
                              "type": "object",
                              "properties": {
                                "toolName": {
                                  "description": "The tool name used to invoke this agent in the workflow.",
                                  "type": "string"
                                },
                                "toolDescription": {
                                  "description": "A description of what this agent does, shown to the LLM router.",
                                  "type": "string"
                                },
                                "executionTimeoutSeconds": {
                                  "description": "Wall-clock ceiling for ONE execution of this workflow, in seconds (30-1800). When the deadline passes the run is aborted — in-flight model calls are cancelled, sub-agents included — and the execution finishes with status TIMED_OUT, with the reason recorded on the nodes that were cut. Optional: an agent that declares nothing keeps the platform behavior (no explicit ceiling). Declare it when the agent legitimately runs for minutes (deep research, long tool chains) so a slow run is never mistaken for a hung one, or when it must never occupy a worker past a known bound. The budget is per attempt: a run resumed after a crash starts a fresh timer.",
                                  "type": "integer",
                                  "minimum": 30,
                                  "maximum": 1800
                                },
                                "entryPoints": {
                                  "description": "Entry points into the workflow. MUST contain at least one node ID; an empty array makes the workflow non-executable. When you restructure or rename the first node, update this list in the same operation so it points at the new entry node.",
                                  "minItems": 1,
                                  "type": "array",
                                  "items": {
                                    "anyOf": [
                                      {
                                        "description": "Node ID to use as an unconditional entry point.",
                                        "type": "string"
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "nodeId": {
                                            "description": "The ID of the entry point node.",
                                            "type": "string"
                                          },
                                          "if": {
                                            "description": "Optional condition that must be met for this entry point to activate.",
                                            "$ref": "#/components/schemas/importAgents_schema0"
                                          }
                                        },
                                        "required": [
                                          "nodeId"
                                        ]
                                      }
                                    ]
                                  }
                                },
                                "nodes": {
                                  "description": "The workflow nodes: decision, action, subAgent, end, state, hub, jump, clearCache, javascript, or forEach.",
                                  "type": "array",
                                  "items": {
                                    "anyOf": [
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "decision"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this decision node.",
                                            "type": "string"
                                          },
                                          "evaluationCriteria": {
                                            "description": "Evaluation criteria IDs (string references) or inline criteria objects.",
                                            "type": "array",
                                            "items": {
                                              "anyOf": [
                                                {
                                                  "type": "string"
                                                },
                                                {
                                                  "type": "object",
                                                  "properties": {
                                                    "id": {
                                                      "type": "string"
                                                    },
                                                    "name": {
                                                      "description": "Required non-empty short human-readable name for this criterion (e.g. \"Real-Estate Availability Intent\"). Never an empty string.",
                                                      "type": "string"
                                                    },
                                                    "type": {
                                                      "type": "string",
                                                      "enum": [
                                                        "QUALITY_ENGAGINGNESS",
                                                        "QUALITY_COHERENCE",
                                                        "QUALITY_CONSISTENCY",
                                                        "QUALITY_FLUENCY",
                                                        "QUALITY_RELEVANCE",
                                                        "SECURITY_FINANCIAL_DETECTION",
                                                        "SECURITY_PII_DETECTION",
                                                        "SECURITY_ANOMALOUS_CONVERSATION",
                                                        "PERSONALITY_EXTRAVERSION",
                                                        "PERSONALITY_OPEN_TO_EXPERIENCE",
                                                        "PERSONALITY_CONSCIENTIOUSNESS",
                                                        "PERSONALITY_AGREEABLENESS",
                                                        "PERSONALITY_NEUROTICISM",
                                                        "PERSONALITY_OTHER",
                                                        "DOCUMENT_INSIGHTS",
                                                        "CUSTOM"
                                                      ]
                                                    },
                                                    "evaluationCriteria": {
                                                      "description": "REQUIRED non-empty instruction telling the evaluator what to assess. One or two sentences in plain language: what to evaluate, and — when structuredDataParams is set — how to populate each declared field. Empty strings, null, or omission are forbidden; an empty description leaves the reasoning useless. Example: \"Decide whether the user is asking about real-estate availability. Set isAvailability to true only when the user is clearly asking whether a property is available; otherwise false.\"",
                                                      "type": "string"
                                                    },
                                                    "evaluationSteps": {
                                                      "type": "array",
                                                      "items": {
                                                        "type": "string"
                                                      }
                                                    },
                                                    "structuredDataParams": {
                                                      "anyOf": [
                                                        {
                                                          "type": "object",
                                                          "propertyNames": {
                                                            "type": "string"
                                                          },
                                                          "additionalProperties": {}
                                                        },
                                                        {
                                                          "type": "null"
                                                        }
                                                      ]
                                                    },
                                                    "metadata": {
                                                      "anyOf": [
                                                        {
                                                          "type": "object",
                                                          "propertyNames": {
                                                            "type": "string"
                                                          },
                                                          "additionalProperties": {}
                                                        },
                                                        {
                                                          "type": "null"
                                                        }
                                                      ]
                                                    },
                                                    "enabled": {
                                                      "type": "boolean"
                                                    },
                                                    "applicationId": {
                                                      "type": "number"
                                                    },
                                                    "evaluationParams": {
                                                      "type": "array",
                                                      "items": {
                                                        "type": "string",
                                                        "enum": [
                                                          "INPUT",
                                                          "ACTUAL_OUTPUT",
                                                          "EXPECTED_OUTPUT",
                                                          "CONTEXT",
                                                          "RETRIEVAL_CONTEXT",
                                                          "EXECUTION_CONTEXT"
                                                        ]
                                                      }
                                                    }
                                                  },
                                                  "required": [
                                                    "name",
                                                    "type",
                                                    "evaluationCriteria"
                                                  ]
                                                }
                                              ]
                                            }
                                          },
                                          "transition": {
                                            "description": "Transitions to other nodes based on evaluation results.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/importAgents_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ]
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ]
                                            }
                                          },
                                          "cachePolicy": {
                                            "description": "Controls execution caching for this decision node across messages in a conversation. auto (default): cache result and use a lightweight guard evaluation to detect staleness. always: always use cached result until explicitly cleared. never: always re-evaluate all criteria every message (disables caching).",
                                            "type": "string",
                                            "enum": [
                                              "auto",
                                              "always",
                                              "never"
                                            ]
                                          },
                                          "selectionPolicy": {
                                            "description": "Controls which enabled criteria are evaluated each message. all (default): every enabled criterion runs. contextual: a lightweight router selects only the criteria relevant to the current input and conversation state; the rest are skipped. Skipped criteria are not evaluated, so their structuredData fields are absent downstream (route on them with the \"exists\"/\"notExists\" operators) and scores.mean reflects only the criteria that ran.",
                                            "type": "string",
                                            "enum": [
                                              "all",
                                              "contextual"
                                            ]
                                          },
                                          "alwaysRunCriteria": {
                                            "description": "Only used when selectionPolicy is \"contextual\": IDs of evaluation criteria that always run (they bypass the router); every other criterion is AI-selected per message. Use this to pin extractors whose structuredData a downstream node depends on. Ignored when selectionPolicy is \"all\".",
                                            "type": "array",
                                            "items": {
                                              "type": "string"
                                            }
                                          },
                                          "contextualSelectionPrompt": {
                                            "description": "Only used when selectionPolicy is \"contextual\": extra author guidance appended to the built-in router prompt to steer which criteria it picks (e.g. \"prefer running Consultar NFSe whenever the user mentions a nota fiscal, even indirectly\"). It augments the router — it does not replace its output contract or the safe fallback of running everything. Ignored when selectionPolicy is \"all\".",
                                            "type": "string"
                                          },
                                          "routingPolicy": {
                                            "description": "How many REASONINGS (criteria) may win the routing on this node per message. all (default): every matching conditional transition fires in parallel. bestReasoning: only the highest-scoring reasoning wins — ALL matched transitions whose condition is anchored on it fire (they are that reasoning's flow), everything anchored on other reasonings is suppressed. topReasonings: like bestReasoning but the best `maxReasonings` reasonings win. A matched transition is anchored on the highest-scoring criterion its condition references (via \"resultsById.<id>.score\" paths, at any nesting). Score ties between reasonings break by position in this node's evaluationCriteria list (earlier wins) — reorder the list to set priority. Matched transitions that reference NO criterion score (pure structuredData/context/state conditions) are outside the competition and always fire, like \"default\" and unconditional transitions. Criteria evaluation is unaffected — this arbitrates AFTER scoring, so it is the reliable way to get \"only one reasoning wins\" (independent per-criterion evaluations cannot be prompted into exclusivity).",
                                            "type": "string",
                                            "enum": [
                                              "all",
                                              "bestReasoning",
                                              "topReasonings"
                                            ]
                                          },
                                          "maxReasonings": {
                                            "description": "Only used when routingPolicy is \"topReasonings\": how many of the highest-scoring reasonings win the routing. Ignored for other policies (\"bestReasoning\" is exactly maxReasonings = 1).",
                                            "type": "integer",
                                            "minimum": 1,
                                            "maximum": 9007199254740991
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type",
                                          "evaluationCriteria",
                                          "transition"
                                        ]
                                      },
                                      {
                                        "oneOf": [
                                          {
                                            "type": "object",
                                            "properties": {
                                              "id": {
                                                "description": "Unique identifier for this node.",
                                                "type": "string"
                                              },
                                              "type": {
                                                "type": "string",
                                                "const": "action"
                                              },
                                              "label": {
                                                "description": "Human-readable label for this action node.",
                                                "type": "string"
                                              },
                                              "mode": {
                                                "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                "type": "string",
                                                "enum": [
                                                  "sync",
                                                  "async"
                                                ]
                                              },
                                              "outputVar": {
                                                "description": "Variable name to store the action output for use by downstream nodes.",
                                                "type": "string"
                                              },
                                              "transition": {
                                                "description": "Transitions to other nodes after this action completes.",
                                                "type": "array",
                                                "items": {
                                                  "type": "object",
                                                  "properties": {
                                                    "if": {
                                                      "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                      "$ref": "#/components/schemas/importAgents_schema0"
                                                    },
                                                    "default": {
                                                      "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                      "type": "boolean"
                                                    },
                                                    "to": {
                                                      "type": "object",
                                                      "properties": {
                                                        "nodeId": {
                                                          "description": "The ID of the target node to transition to.",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "required": [
                                                        "nodeId"
                                                      ]
                                                    },
                                                    "stop": {
                                                      "description": "If true, stop execution after this transition.",
                                                      "type": "boolean"
                                                    }
                                                  },
                                                  "required": [
                                                    "to"
                                                  ]
                                                }
                                              },
                                              "actionType": {
                                                "type": "string",
                                                "const": "INSTRUCTIONS"
                                              },
                                              "config": {
                                                "type": "object",
                                                "properties": {
                                                  "instructions": {
                                                    "description": "The instructions for the LLM to execute.",
                                                    "type": "string"
                                                  },
                                                  "modelTier": {
                                                    "description": "The model tier to use for this instruction. Defaults to regular.",
                                                    "type": "string",
                                                    "enum": [
                                                      "lite",
                                                      "regular",
                                                      "pro"
                                                    ]
                                                  },
                                                  "thinkingEffortPct": {
                                                    "description": "Thinking effort percentage (0-100) controlling how much reasoning the model applies.",
                                                    "type": "number",
                                                    "minimum": 0,
                                                    "maximum": 100
                                                  },
                                                  "maxOutputTokens": {
                                                    "description": "Maximum tokens the model may generate for this node. On thinking models the budget is SHARED between reasoning and output — reasoning routinely consumes most of it — so a node whose structured output is truncated is usually better served by lowering thinkingEffortPct than by raising this. Defaults to the model maximum when omitted.",
                                                    "type": "integer",
                                                    "minimum": 1,
                                                    "maximum": 9007199254740991
                                                  },
                                                  "maxRetries": {
                                                    "description": "How many times this node retries a failed model call. Defaults to 2 when the node has an outputSchema and 5 otherwise. Raise it for nodes whose long outputs are exposed to dropped provider streams; it does not help failures the model reproduces deterministically.",
                                                    "type": "integer",
                                                    "minimum": 1,
                                                    "maximum": 10
                                                  },
                                                  "toolChoiceMode": {
                                                    "description": "Tool selection mode for this instruction. Defaults to auto when omitted.",
                                                    "type": "string",
                                                    "enum": [
                                                      "auto",
                                                      "none",
                                                      "tool",
                                                      "tools"
                                                    ]
                                                  },
                                                  "toolChoiceToolName": {
                                                    "description": "When toolChoiceMode is \"tool\", the specific tool name to force.",
                                                    "type": "string"
                                                  },
                                                  "toolChoiceToolNames": {
                                                    "description": "When toolChoiceMode is \"tools\", the list of allowed tool names.",
                                                    "type": "array",
                                                    "items": {
                                                      "type": "string"
                                                    }
                                                  },
                                                  "suppressTextResponse": {
                                                    "description": "When true, text output from the LLM is suppressed and only tool-call results are emitted. Useful when the instruction should only invoke tools (e.g., displayMedia) without generating follow-up text.",
                                                    "type": "boolean"
                                                  },
                                                  "stopAfterFirstToolCall": {
                                                    "description": "When true and a single tool is forced with text suppressed, the instruction stops after the first successful tool call. Defaults to false, which allows the tool to be called across multiple steps.",
                                                    "type": "boolean"
                                                  },
                                                  "internal": {
                                                    "description": "When true, this node is an intermediate step: its text/structured output is NOT shown to the user (not streamed, not persisted as a visible message part) and is only captured into the node's outputVar for downstream nodes. Reasoning and tool-call activity chips remain visible. Use for internal hand-offs (e.g. tool-driven data synthesis a later node consumes); the user-facing reply should come from a later, non-internal node.",
                                                    "type": "boolean"
                                                  },
                                                  "outputSchema": {
                                                    "description": "JSON Schema for structured output. When provided, the LLM will output valid JSON matching this schema instead of free-form text.",
                                                    "type": "object",
                                                    "properties": {
                                                      "type": {
                                                        "description": "JSON Schema type, must be \"object\" for structured output.",
                                                        "type": "string",
                                                        "const": "object"
                                                      },
                                                      "properties": {
                                                        "description": "Schema properties defining the expected output structure.",
                                                        "type": "object",
                                                        "propertyNames": {
                                                          "type": "string"
                                                        },
                                                        "additionalProperties": {}
                                                      },
                                                      "required": {
                                                        "description": "Array of required property names.",
                                                        "type": "array",
                                                        "items": {
                                                          "type": "string"
                                                        }
                                                      },
                                                      "additionalProperties": {
                                                        "description": "Whether to allow additional properties not defined in the schema.",
                                                        "type": "boolean"
                                                      },
                                                      "description": {
                                                        "description": "Description of the expected output to guide the LLM.",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "type",
                                                      "properties"
                                                    ]
                                                  },
                                                  "grounding": {
                                                    "description": "Model-side grounding for this node. Only Google Search is available today.",
                                                    "type": "object",
                                                    "properties": {
                                                      "googleSearch": {
                                                        "description": "Enable Google Search grounding: the model searches the public web (via Gemini's built-in google_search tool) while executing this instruction and answers from what it finds. Set `{}` to enable with defaults. The node result then carries `grounding` — the queries Google ran and the sources it cited, each with the resolved article URL, its domain and the passages of the reply it supports — readable downstream as `nodes.<nodeId>.grounding` in javascript nodes and templates; the text/JSON reply itself still flows through outputVar as usual. With an outputSchema the search runs first and the JSON is synthesized afterwards with the numbered source list, so declare a `sourceIds` or `url` field if you want citations inside the structured output. Incompatible with toolChoiceMode \"tool\" and with suppressTextResponse (a forced tool call and Google Search in one request returns an empty reply); with toolChoiceMode \"none\" the node still searches but calls no other tool. Each prompt costs Google one search query per query the model decides to run (usually 4–10), billed per query beyond the project's free tier.",
                                                        "type": "object",
                                                        "properties": {
                                                          "excludeDomains": {
                                                            "description": "Domains Google Search must not ground on, e.g. [\"youtube.com\", \"reddit.com\"]. A domain excludes its subdomains too.",
                                                            "type": "array",
                                                            "items": {
                                                              "type": "string"
                                                            }
                                                          }
                                                        }
                                                      }
                                                    }
                                                  },
                                                  "urlContext": {
                                                    "description": "Gemini URL context: hand the model a list of URLs to READ IN FULL server-side instead of fetching their text into a variable first. The URLs come from the fixed \"urls\" list, from the \"from\" value path, or from both (fixed first). They are appended to the end of the instruction and the provider fetches and reads the pages inside the same call. With an outputSchema the node runs as a SINGLE call (reading and synthesis must share it), so pair it with toolChoiceMode \"none\" unless the node truly needs function tools. Limits: 20 URLs per call (extra ones are dropped and reported as `truncated`), public pages only — paywalls, Google News redirect links and private hosts fail. The model may skip fetching when the URLs sit inside a very long prompt, so prefer a dedicated short reading node over bolting URLs onto a large synthesis prompt. The node output carries `urlContext.{requested,retrieved,unread,truncated,invalid,unresolved,supported,tokens}`. `unread` is the integrity signal — it lists every URL the model did not read, including the ones dropped by the 20-URL cap — so branch on `nodes.<id>.urlContext.unread` for a fallback reader (inside a forEach body it holds only the last item). `unresolved` says the \"from\" path resolved to nothing, `invalid` lists entries that were not http(s) URLs, and `supported` is false when the model could not carry the tool: in those cases nothing was read at all. Retrieved page content is billed as input tokens and added to the node usage as `urlContextTokens`. Gemini 3+ models only.",
                                                    "type": "object",
                                                    "properties": {
                                                      "urls": {
                                                        "description": "Fixed http(s) URLs to read on every run, written out here — for pages that do not change per execution (a status page, a policy, a price list). Combine with \"from\" to read a fixed set plus whatever the run produced; the two lists concatenate, fixed URLs first.",
                                                        "type": "array",
                                                        "items": {
                                                          "type": "string"
                                                        }
                                                      },
                                                      "from": {
                                                        "description": "Dotted VALUE PATH (same resolution as forEach \"over\": workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — e.g. \"paraLer.soUrls\" or \"nodes.pick.result.urls\") to a URL list the run produced: an array of http(s) URL strings, a single URL string, or a JSON-encoded array string. Not a Handlebars template; a path wrapped in {{ }} is accepted and unwrapped.",
                                                        "type": "string",
                                                        "minLength": 1
                                                      }
                                                    }
                                                  }
                                                },
                                                "required": [
                                                  "instructions"
                                                ]
                                              }
                                            },
                                            "required": [
                                              "id",
                                              "type",
                                              "mode",
                                              "transition",
                                              "actionType",
                                              "config"
                                            ]
                                          },
                                          {
                                            "type": "object",
                                            "properties": {
                                              "id": {
                                                "description": "Unique identifier for this node.",
                                                "type": "string"
                                              },
                                              "type": {
                                                "type": "string",
                                                "const": "action"
                                              },
                                              "label": {
                                                "description": "Human-readable label for this action node.",
                                                "type": "string"
                                              },
                                              "mode": {
                                                "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                "type": "string",
                                                "enum": [
                                                  "sync",
                                                  "async"
                                                ]
                                              },
                                              "outputVar": {
                                                "description": "Variable name to store the action output for use by downstream nodes.",
                                                "type": "string"
                                              },
                                              "transition": {
                                                "description": "Transitions to other nodes after this action completes.",
                                                "type": "array",
                                                "items": {
                                                  "type": "object",
                                                  "properties": {
                                                    "if": {
                                                      "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                      "$ref": "#/components/schemas/importAgents_schema0"
                                                    },
                                                    "default": {
                                                      "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                      "type": "boolean"
                                                    },
                                                    "to": {
                                                      "type": "object",
                                                      "properties": {
                                                        "nodeId": {
                                                          "description": "The ID of the target node to transition to.",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "required": [
                                                        "nodeId"
                                                      ]
                                                    },
                                                    "stop": {
                                                      "description": "If true, stop execution after this transition.",
                                                      "type": "boolean"
                                                    }
                                                  },
                                                  "required": [
                                                    "to"
                                                  ]
                                                }
                                              },
                                              "actionType": {
                                                "type": "string",
                                                "const": "EMAIL"
                                              },
                                              "config": {
                                                "type": "object",
                                                "properties": {
                                                  "to": {
                                                    "type": "string"
                                                  },
                                                  "senderType": {
                                                    "type": "string",
                                                    "enum": [
                                                      "default",
                                                      "gmail"
                                                    ]
                                                  },
                                                  "gmailIntegrationId": {
                                                    "type": "string"
                                                  },
                                                  "subject": {
                                                    "type": "string"
                                                  },
                                                  "body": {
                                                    "type": "string"
                                                  },
                                                  "cc": {
                                                    "type": "string"
                                                  },
                                                  "bcc": {
                                                    "type": "string"
                                                  },
                                                  "attachments": {
                                                    "type": "array",
                                                    "items": {
                                                      "type": "object",
                                                      "properties": {
                                                        "documentId": {
                                                          "type": "number"
                                                        },
                                                        "url": {
                                                          "type": "string"
                                                        },
                                                        "filename": {
                                                          "type": "string"
                                                        }
                                                      }
                                                    }
                                                  },
                                                  "templateId": {
                                                    "type": "string"
                                                  },
                                                  "templateName": {
                                                    "type": "string"
                                                  },
                                                  "applicationId": {
                                                    "type": "number"
                                                  }
                                                },
                                                "required": [
                                                  "to",
                                                  "subject",
                                                  "body"
                                                ]
                                              }
                                            },
                                            "required": [
                                              "id",
                                              "type",
                                              "mode",
                                              "transition",
                                              "actionType",
                                              "config"
                                            ]
                                          },
                                          {
                                            "type": "object",
                                            "properties": {
                                              "id": {
                                                "description": "Unique identifier for this node.",
                                                "type": "string"
                                              },
                                              "type": {
                                                "type": "string",
                                                "const": "action"
                                              },
                                              "label": {
                                                "description": "Human-readable label for this action node.",
                                                "type": "string"
                                              },
                                              "mode": {
                                                "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                "type": "string",
                                                "enum": [
                                                  "sync",
                                                  "async"
                                                ]
                                              },
                                              "outputVar": {
                                                "description": "Variable name to store the action output for use by downstream nodes.",
                                                "type": "string"
                                              },
                                              "transition": {
                                                "description": "Transitions to other nodes after this action completes.",
                                                "type": "array",
                                                "items": {
                                                  "type": "object",
                                                  "properties": {
                                                    "if": {
                                                      "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                      "$ref": "#/components/schemas/importAgents_schema0"
                                                    },
                                                    "default": {
                                                      "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                      "type": "boolean"
                                                    },
                                                    "to": {
                                                      "type": "object",
                                                      "properties": {
                                                        "nodeId": {
                                                          "description": "The ID of the target node to transition to.",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "required": [
                                                        "nodeId"
                                                      ]
                                                    },
                                                    "stop": {
                                                      "description": "If true, stop execution after this transition.",
                                                      "type": "boolean"
                                                    }
                                                  },
                                                  "required": [
                                                    "to"
                                                  ]
                                                }
                                              },
                                              "actionType": {
                                                "type": "string",
                                                "const": "WEBHOOK"
                                              },
                                              "config": {
                                                "type": "object",
                                                "properties": {
                                                  "url": {
                                                    "type": "string"
                                                  },
                                                  "method": {
                                                    "type": "string",
                                                    "enum": [
                                                      "GET",
                                                      "POST",
                                                      "PUT",
                                                      "PATCH",
                                                      "DELETE"
                                                    ]
                                                  },
                                                  "headers": {
                                                    "type": "object",
                                                    "propertyNames": {
                                                      "type": "string"
                                                    },
                                                    "additionalProperties": {
                                                      "type": "string"
                                                    }
                                                  },
                                                  "queryParams": {
                                                    "type": "object",
                                                    "propertyNames": {
                                                      "type": "string"
                                                    },
                                                    "additionalProperties": {
                                                      "type": "string"
                                                    }
                                                  },
                                                  "body": {
                                                    "type": "string"
                                                  },
                                                  "timeout": {
                                                    "type": "number"
                                                  },
                                                  "responseMode": {
                                                    "description": "How to decode the response body. \"json\" (default): parse as JSON/text and expose via varsDelta. \"attachment\": read as binary bytes for multimodal input (e.g. PDFs, images).",
                                                    "type": "string",
                                                    "enum": [
                                                      "json",
                                                      "attachment"
                                                    ]
                                                  },
                                                  "asMessage": {
                                                    "description": "When true, append the response to the conversation as a new user message so downstream LLM nodes see it. In \"attachment\" mode the message carries a file content part; in \"json\" mode it carries the stringified body as text. Defaults to false — preserving the historical behavior where webhook responses only flow through varsDelta.",
                                                    "type": "boolean"
                                                  },
                                                  "suppressNoResponseFallback": {
                                                    "description": "Marks the webhook as a fire-and-forget trigger: the conversation is meant to end here, with the rest happening on the receiving system. When the call succeeds and the turn finishes without sending anything to the user, the channel skips its automatic \"sorry, something went wrong\" fallback message. A failed call (HTTP >= 400) still gets the fallback, since the user is then left waiting for nothing.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "url",
                                                  "method"
                                                ]
                                              }
                                            },
                                            "required": [
                                              "id",
                                              "type",
                                              "mode",
                                              "transition",
                                              "actionType",
                                              "config"
                                            ]
                                          },
                                          {
                                            "type": "object",
                                            "properties": {
                                              "id": {
                                                "description": "Unique identifier for this node.",
                                                "type": "string"
                                              },
                                              "type": {
                                                "type": "string",
                                                "const": "action"
                                              },
                                              "label": {
                                                "description": "Human-readable label for this action node.",
                                                "type": "string"
                                              },
                                              "mode": {
                                                "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                "type": "string",
                                                "enum": [
                                                  "sync",
                                                  "async"
                                                ]
                                              },
                                              "outputVar": {
                                                "description": "Variable name to store the action output for use by downstream nodes.",
                                                "type": "string"
                                              },
                                              "transition": {
                                                "description": "Transitions to other nodes after this action completes.",
                                                "type": "array",
                                                "items": {
                                                  "type": "object",
                                                  "properties": {
                                                    "if": {
                                                      "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                      "$ref": "#/components/schemas/importAgents_schema0"
                                                    },
                                                    "default": {
                                                      "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                      "type": "boolean"
                                                    },
                                                    "to": {
                                                      "type": "object",
                                                      "properties": {
                                                        "nodeId": {
                                                          "description": "The ID of the target node to transition to.",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "required": [
                                                        "nodeId"
                                                      ]
                                                    },
                                                    "stop": {
                                                      "description": "If true, stop execution after this transition.",
                                                      "type": "boolean"
                                                    }
                                                  },
                                                  "required": [
                                                    "to"
                                                  ]
                                                }
                                              },
                                              "actionType": {
                                                "type": "string",
                                                "const": "DOCUMENT_TEMPLATE"
                                              },
                                              "config": {
                                                "type": "object",
                                                "properties": {
                                                  "templateId": {
                                                    "type": "string"
                                                  },
                                                  "templateName": {
                                                    "type": "string"
                                                  },
                                                  "sendEmail": {
                                                    "type": "boolean"
                                                  },
                                                  "sendWhatsApp": {
                                                    "type": "boolean"
                                                  },
                                                  "recipientEmail": {
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "templateId"
                                                ]
                                              }
                                            },
                                            "required": [
                                              "id",
                                              "type",
                                              "mode",
                                              "transition",
                                              "actionType",
                                              "config"
                                            ]
                                          },
                                          {
                                            "type": "object",
                                            "properties": {
                                              "id": {
                                                "description": "Unique identifier for this node.",
                                                "type": "string"
                                              },
                                              "type": {
                                                "type": "string",
                                                "const": "action"
                                              },
                                              "label": {
                                                "description": "Human-readable label for this action node.",
                                                "type": "string"
                                              },
                                              "mode": {
                                                "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                "type": "string",
                                                "enum": [
                                                  "sync",
                                                  "async"
                                                ]
                                              },
                                              "outputVar": {
                                                "description": "Variable name to store the action output for use by downstream nodes.",
                                                "type": "string"
                                              },
                                              "transition": {
                                                "description": "Transitions to other nodes after this action completes.",
                                                "type": "array",
                                                "items": {
                                                  "type": "object",
                                                  "properties": {
                                                    "if": {
                                                      "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                      "$ref": "#/components/schemas/importAgents_schema0"
                                                    },
                                                    "default": {
                                                      "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                      "type": "boolean"
                                                    },
                                                    "to": {
                                                      "type": "object",
                                                      "properties": {
                                                        "nodeId": {
                                                          "description": "The ID of the target node to transition to.",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "required": [
                                                        "nodeId"
                                                      ]
                                                    },
                                                    "stop": {
                                                      "description": "If true, stop execution after this transition.",
                                                      "type": "boolean"
                                                    }
                                                  },
                                                  "required": [
                                                    "to"
                                                  ]
                                                }
                                              },
                                              "actionType": {
                                                "type": "string",
                                                "const": "TOOL_CALL"
                                              },
                                              "config": {
                                                "type": "object",
                                                "properties": {
                                                  "toolName": {
                                                    "description": "The name of the common tool to invoke.",
                                                    "type": "string"
                                                  },
                                                  "parameters": {
                                                    "description": "Per-parameter configuration. Keys are parameter names from the tool schema.",
                                                    "type": "object",
                                                    "propertyNames": {
                                                      "type": "string"
                                                    },
                                                    "additionalProperties": {
                                                      "type": "object",
                                                      "properties": {
                                                        "mode": {
                                                          "description": "Whether this parameter is hardcoded (static) or filled by the LLM at runtime (dynamic).",
                                                          "type": "string",
                                                          "enum": [
                                                            "static",
                                                            "dynamic"
                                                          ]
                                                        },
                                                        "staticValue": {
                                                          "description": "The fixed value for this parameter. Required when mode is \"static\"."
                                                        },
                                                        "instructions": {
                                                          "description": "Optional guidance for the LLM when filling this parameter (only used when mode is \"dynamic\").",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "required": [
                                                        "mode"
                                                      ]
                                                    }
                                                  },
                                                  "instructions": {
                                                    "description": "General instructions for the LLM when resolving dynamic parameters.",
                                                    "type": "string"
                                                  },
                                                  "skipKnowledgeSearch": {
                                                    "description": "When a node has dynamic parameters, the model is normally forced to call similaritySearch first so parameter values are grounded in the knowledge base, costing one extra model round. Set true for tools that need no knowledge context (for example code execution) to call the configured tool directly. Ignored when every parameter is static, since no model runs at all.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "toolName"
                                                ]
                                              }
                                            },
                                            "required": [
                                              "id",
                                              "type",
                                              "mode",
                                              "transition",
                                              "actionType",
                                              "config"
                                            ]
                                          },
                                          {
                                            "type": "object",
                                            "properties": {
                                              "id": {
                                                "description": "Unique identifier for this node.",
                                                "type": "string"
                                              },
                                              "type": {
                                                "type": "string",
                                                "const": "action"
                                              },
                                              "label": {
                                                "description": "Human-readable label for this action node.",
                                                "type": "string"
                                              },
                                              "mode": {
                                                "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                "type": "string",
                                                "enum": [
                                                  "sync",
                                                  "async"
                                                ]
                                              },
                                              "outputVar": {
                                                "description": "Variable name to store the action output for use by downstream nodes.",
                                                "type": "string"
                                              },
                                              "transition": {
                                                "description": "Transitions to other nodes after this action completes.",
                                                "type": "array",
                                                "items": {
                                                  "type": "object",
                                                  "properties": {
                                                    "if": {
                                                      "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                      "$ref": "#/components/schemas/importAgents_schema0"
                                                    },
                                                    "default": {
                                                      "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                      "type": "boolean"
                                                    },
                                                    "to": {
                                                      "type": "object",
                                                      "properties": {
                                                        "nodeId": {
                                                          "description": "The ID of the target node to transition to.",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "required": [
                                                        "nodeId"
                                                      ]
                                                    },
                                                    "stop": {
                                                      "description": "If true, stop execution after this transition.",
                                                      "type": "boolean"
                                                    }
                                                  },
                                                  "required": [
                                                    "to"
                                                  ]
                                                }
                                              },
                                              "actionType": {
                                                "type": "string",
                                                "const": "FOLLOW_UP"
                                              },
                                              "config": {
                                                "type": "object",
                                                "properties": {
                                                  "delayMinutes": {
                                                    "description": "Minutes to wait before checking whether to run the inner action. Common presets: 5, 10, 15. Maximum 1440 (24h). Cloud Scheduler is cron-based so the actual fire time is rounded to the next minute boundary.",
                                                    "type": "integer",
                                                    "minimum": 1,
                                                    "maximum": 1440
                                                  },
                                                  "cancelOnUserMessage": {
                                                    "description": "When true (default), skip the inner action if any USER message arrived after the node was reached. Set to false only if the follow-up should fire even after the user has replied.",
                                                    "type": "boolean"
                                                  },
                                                  "cancelOnAssistantMessage": {
                                                    "description": "When true (default), skip the inner action if any ASSISTANT text message was sent after the node was reached. Tool-only assistant messages (no text content) do NOT count. Prevents double-pinging when another node already produced a response.",
                                                    "type": "boolean"
                                                  },
                                                  "cancelOnArchive": {
                                                    "description": "When true (default), skip the inner action if the thread was archived between scheduling and firing.",
                                                    "type": "boolean"
                                                  },
                                                  "action": {
                                                    "description": "The inner action to run when the delay elapses and cancel rules pass. INSTRUCTIONS produces an LLM-generated text message (good for \"Are you still there?\"-style nudges). TOOL_CALL fires a display tool (good for offering options or showing media).",
                                                    "oneOf": [
                                                      {
                                                        "type": "object",
                                                        "properties": {
                                                          "actionType": {
                                                            "type": "string",
                                                            "const": "INSTRUCTIONS"
                                                          },
                                                          "config": {
                                                            "type": "object",
                                                            "properties": {
                                                              "instructions": {
                                                                "description": "The instructions for the LLM to execute.",
                                                                "type": "string"
                                                              },
                                                              "modelTier": {
                                                                "description": "The model tier to use for this instruction. Defaults to regular.",
                                                                "type": "string",
                                                                "enum": [
                                                                  "lite",
                                                                  "regular",
                                                                  "pro"
                                                                ]
                                                              },
                                                              "thinkingEffortPct": {
                                                                "description": "Thinking effort percentage (0-100) controlling how much reasoning the model applies.",
                                                                "type": "number",
                                                                "minimum": 0,
                                                                "maximum": 100
                                                              },
                                                              "maxOutputTokens": {
                                                                "description": "Maximum tokens the model may generate for this node. On thinking models the budget is SHARED between reasoning and output — reasoning routinely consumes most of it — so a node whose structured output is truncated is usually better served by lowering thinkingEffortPct than by raising this. Defaults to the model maximum when omitted.",
                                                                "type": "integer",
                                                                "minimum": 1,
                                                                "maximum": 9007199254740991
                                                              },
                                                              "maxRetries": {
                                                                "description": "How many times this node retries a failed model call. Defaults to 2 when the node has an outputSchema and 5 otherwise. Raise it for nodes whose long outputs are exposed to dropped provider streams; it does not help failures the model reproduces deterministically.",
                                                                "type": "integer",
                                                                "minimum": 1,
                                                                "maximum": 10
                                                              },
                                                              "toolChoiceMode": {
                                                                "description": "Tool selection mode for this instruction. Defaults to auto when omitted.",
                                                                "type": "string",
                                                                "enum": [
                                                                  "auto",
                                                                  "none",
                                                                  "tool",
                                                                  "tools"
                                                                ]
                                                              },
                                                              "toolChoiceToolName": {
                                                                "description": "When toolChoiceMode is \"tool\", the specific tool name to force.",
                                                                "type": "string"
                                                              },
                                                              "toolChoiceToolNames": {
                                                                "description": "When toolChoiceMode is \"tools\", the list of allowed tool names.",
                                                                "type": "array",
                                                                "items": {
                                                                  "type": "string"
                                                                }
                                                              },
                                                              "suppressTextResponse": {
                                                                "description": "When true, text output from the LLM is suppressed and only tool-call results are emitted. Useful when the instruction should only invoke tools (e.g., displayMedia) without generating follow-up text.",
                                                                "type": "boolean"
                                                              },
                                                              "stopAfterFirstToolCall": {
                                                                "description": "When true and a single tool is forced with text suppressed, the instruction stops after the first successful tool call. Defaults to false, which allows the tool to be called across multiple steps.",
                                                                "type": "boolean"
                                                              },
                                                              "internal": {
                                                                "description": "When true, this node is an intermediate step: its text/structured output is NOT shown to the user (not streamed, not persisted as a visible message part) and is only captured into the node's outputVar for downstream nodes. Reasoning and tool-call activity chips remain visible. Use for internal hand-offs (e.g. tool-driven data synthesis a later node consumes); the user-facing reply should come from a later, non-internal node.",
                                                                "type": "boolean"
                                                              },
                                                              "outputSchema": {
                                                                "description": "JSON Schema for structured output. When provided, the LLM will output valid JSON matching this schema instead of free-form text.",
                                                                "type": "object",
                                                                "properties": {
                                                                  "type": {
                                                                    "description": "JSON Schema type, must be \"object\" for structured output.",
                                                                    "type": "string",
                                                                    "const": "object"
                                                                  },
                                                                  "properties": {
                                                                    "description": "Schema properties defining the expected output structure.",
                                                                    "type": "object",
                                                                    "propertyNames": {
                                                                      "type": "string"
                                                                    },
                                                                    "additionalProperties": {}
                                                                  },
                                                                  "required": {
                                                                    "description": "Array of required property names.",
                                                                    "type": "array",
                                                                    "items": {
                                                                      "type": "string"
                                                                    }
                                                                  },
                                                                  "additionalProperties": {
                                                                    "description": "Whether to allow additional properties not defined in the schema.",
                                                                    "type": "boolean"
                                                                  },
                                                                  "description": {
                                                                    "description": "Description of the expected output to guide the LLM.",
                                                                    "type": "string"
                                                                  }
                                                                },
                                                                "required": [
                                                                  "type",
                                                                  "properties"
                                                                ]
                                                              },
                                                              "grounding": {
                                                                "description": "Model-side grounding for this node. Only Google Search is available today.",
                                                                "type": "object",
                                                                "properties": {
                                                                  "googleSearch": {
                                                                    "description": "Enable Google Search grounding: the model searches the public web (via Gemini's built-in google_search tool) while executing this instruction and answers from what it finds. Set `{}` to enable with defaults. The node result then carries `grounding` — the queries Google ran and the sources it cited, each with the resolved article URL, its domain and the passages of the reply it supports — readable downstream as `nodes.<nodeId>.grounding` in javascript nodes and templates; the text/JSON reply itself still flows through outputVar as usual. With an outputSchema the search runs first and the JSON is synthesized afterwards with the numbered source list, so declare a `sourceIds` or `url` field if you want citations inside the structured output. Incompatible with toolChoiceMode \"tool\" and with suppressTextResponse (a forced tool call and Google Search in one request returns an empty reply); with toolChoiceMode \"none\" the node still searches but calls no other tool. Each prompt costs Google one search query per query the model decides to run (usually 4–10), billed per query beyond the project's free tier.",
                                                                    "type": "object",
                                                                    "properties": {
                                                                      "excludeDomains": {
                                                                        "description": "Domains Google Search must not ground on, e.g. [\"youtube.com\", \"reddit.com\"]. A domain excludes its subdomains too.",
                                                                        "type": "array",
                                                                        "items": {
                                                                          "type": "string"
                                                                        }
                                                                      }
                                                                    }
                                                                  }
                                                                }
                                                              },
                                                              "urlContext": {
                                                                "description": "Gemini URL context: hand the model a list of URLs to READ IN FULL server-side instead of fetching their text into a variable first. The URLs come from the fixed \"urls\" list, from the \"from\" value path, or from both (fixed first). They are appended to the end of the instruction and the provider fetches and reads the pages inside the same call. With an outputSchema the node runs as a SINGLE call (reading and synthesis must share it), so pair it with toolChoiceMode \"none\" unless the node truly needs function tools. Limits: 20 URLs per call (extra ones are dropped and reported as `truncated`), public pages only — paywalls, Google News redirect links and private hosts fail. The model may skip fetching when the URLs sit inside a very long prompt, so prefer a dedicated short reading node over bolting URLs onto a large synthesis prompt. The node output carries `urlContext.{requested,retrieved,unread,truncated,invalid,unresolved,supported,tokens}`. `unread` is the integrity signal — it lists every URL the model did not read, including the ones dropped by the 20-URL cap — so branch on `nodes.<id>.urlContext.unread` for a fallback reader (inside a forEach body it holds only the last item). `unresolved` says the \"from\" path resolved to nothing, `invalid` lists entries that were not http(s) URLs, and `supported` is false when the model could not carry the tool: in those cases nothing was read at all. Retrieved page content is billed as input tokens and added to the node usage as `urlContextTokens`. Gemini 3+ models only.",
                                                                "type": "object",
                                                                "properties": {
                                                                  "urls": {
                                                                    "description": "Fixed http(s) URLs to read on every run, written out here — for pages that do not change per execution (a status page, a policy, a price list). Combine with \"from\" to read a fixed set plus whatever the run produced; the two lists concatenate, fixed URLs first.",
                                                                    "type": "array",
                                                                    "items": {
                                                                      "type": "string"
                                                                    }
                                                                  },
                                                                  "from": {
                                                                    "description": "Dotted VALUE PATH (same resolution as forEach \"over\": workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — e.g. \"paraLer.soUrls\" or \"nodes.pick.result.urls\") to a URL list the run produced: an array of http(s) URL strings, a single URL string, or a JSON-encoded array string. Not a Handlebars template; a path wrapped in {{ }} is accepted and unwrapped.",
                                                                    "type": "string",
                                                                    "minLength": 1
                                                                  }
                                                                }
                                                              }
                                                            },
                                                            "required": [
                                                              "instructions"
                                                            ]
                                                          }
                                                        },
                                                        "required": [
                                                          "actionType",
                                                          "config"
                                                        ]
                                                      },
                                                      {
                                                        "type": "object",
                                                        "properties": {
                                                          "actionType": {
                                                            "type": "string",
                                                            "const": "TOOL_CALL"
                                                          },
                                                          "config": {
                                                            "type": "object",
                                                            "properties": {
                                                              "toolName": {
                                                                "description": "The name of the common tool to invoke.",
                                                                "type": "string"
                                                              },
                                                              "parameters": {
                                                                "description": "Per-parameter configuration. Keys are parameter names from the tool schema.",
                                                                "type": "object",
                                                                "propertyNames": {
                                                                  "type": "string"
                                                                },
                                                                "additionalProperties": {
                                                                  "type": "object",
                                                                  "properties": {
                                                                    "mode": {
                                                                      "description": "Whether this parameter is hardcoded (static) or filled by the LLM at runtime (dynamic).",
                                                                      "type": "string",
                                                                      "enum": [
                                                                        "static",
                                                                        "dynamic"
                                                                      ]
                                                                    },
                                                                    "staticValue": {
                                                                      "description": "The fixed value for this parameter. Required when mode is \"static\"."
                                                                    },
                                                                    "instructions": {
                                                                      "description": "Optional guidance for the LLM when filling this parameter (only used when mode is \"dynamic\").",
                                                                      "type": "string"
                                                                    }
                                                                  },
                                                                  "required": [
                                                                    "mode"
                                                                  ]
                                                                }
                                                              },
                                                              "instructions": {
                                                                "description": "General instructions for the LLM when resolving dynamic parameters.",
                                                                "type": "string"
                                                              },
                                                              "skipKnowledgeSearch": {
                                                                "description": "When a node has dynamic parameters, the model is normally forced to call similaritySearch first so parameter values are grounded in the knowledge base, costing one extra model round. Set true for tools that need no knowledge context (for example code execution) to call the configured tool directly. Ignored when every parameter is static, since no model runs at all.",
                                                                "type": "boolean"
                                                              }
                                                            },
                                                            "required": [
                                                              "toolName"
                                                            ]
                                                          }
                                                        },
                                                        "required": [
                                                          "actionType",
                                                          "config"
                                                        ]
                                                      }
                                                    ]
                                                  }
                                                },
                                                "required": [
                                                  "delayMinutes",
                                                  "action"
                                                ]
                                              }
                                            },
                                            "required": [
                                              "id",
                                              "type",
                                              "mode",
                                              "transition",
                                              "actionType",
                                              "config"
                                            ]
                                          }
                                        ]
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "subAgent"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this sub-agent node.",
                                            "type": "string"
                                          },
                                          "agentId": {
                                            "description": "The ID of the sub-agent to invoke.",
                                            "type": "string"
                                          },
                                          "instructions": {
                                            "description": "Optional instructions message prepended to the sub-agent conversation. Supports Handlebars interpolation against the parent execution scope: `{{var}}` reads workflow vars, `{{context.x}}` reads contextVars, `{{env.X}}` reads environment, `{{input.text}}` reads the original user input, and `{{nodes.<id>.<path>}}` reads prior node outputs.",
                                            "type": "string"
                                          },
                                          "transition": {
                                            "description": "Optional transitions to continue the flow after the sub-agent returns.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/importAgents_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ]
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ]
                                            }
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type",
                                          "agentId"
                                        ]
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "end"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this end node.",
                                            "type": "string"
                                          },
                                          "config": {
                                            "description": "Optional configuration for the end node behavior.",
                                            "type": "object",
                                            "properties": {
                                              "resetConversationHistory": {
                                                "description": "If true, the next user message starts a new conversation with no prior history.",
                                                "type": "boolean"
                                              }
                                            }
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type"
                                        ]
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "state"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this state node.",
                                            "type": "string"
                                          },
                                          "outputVar": {
                                            "description": "Agent-scope get only: variable name that receives the value stored under `config.key` (null when the key has never been written). Downstream templates read it as `{{<outputVar>}}`; transition conditions as `{source:\"vars\", path:\"<outputVar>...\"}`.",
                                            "type": "string"
                                          },
                                          "config": {
                                            "type": "object",
                                            "properties": {
                                              "scope": {
                                                "description": "How long the data lives and who sees it. execution: this run only. session: this conversation (thread) — a NEW conversation starts empty. agent: durable memory shared by every execution of this agent, across conversations — use it to remember things between independent runs. Survives clearCache.",
                                                "type": "string",
                                                "enum": [
                                                  "execution",
                                                  "session",
                                                  "agent"
                                                ]
                                              },
                                              "operation": {
                                                "description": "Agent scope only (default set). set: durably store the `state` entries. get: read the entry under `key` into `outputVar`. Execution/session scopes are always set — their values are injected into templates automatically, so no get is needed.",
                                                "type": "string",
                                                "enum": [
                                                  "set",
                                                  "get"
                                                ]
                                              },
                                              "key": {
                                                "description": "Agent-scope get: the memory key to read. Supports Handlebars (e.g. \"evidence-{{context.cnpj}}\") so one node can address per-entity entries. Rendered keys are limited to 512 characters.",
                                                "type": "string"
                                              },
                                              "state": {
                                                "description": "Key-value pairs to set (required for set operations). String values support Handlebars. In agent scope the KEYS are templates too (e.g. \"evidence-{{context.cnpj}}\"), each entry is stored as its own durable row, and serialized values are size-capped.",
                                                "type": "object",
                                                "propertyNames": {
                                                  "type": "string"
                                                },
                                                "additionalProperties": {}
                                              }
                                            },
                                            "required": [
                                              "scope"
                                            ]
                                          },
                                          "transition": {
                                            "description": "Optional transitions to continue the flow after setting state.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/importAgents_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ]
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ]
                                            }
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type",
                                          "config"
                                        ]
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "hub"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this hub node.",
                                            "type": "string"
                                          },
                                          "transition": {
                                            "description": "Transitions to route connections to other nodes.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/importAgents_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ]
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ]
                                            }
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type"
                                        ]
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "jump"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this jump node.",
                                            "type": "string"
                                          },
                                          "transition": {
                                            "description": "Target node to jump to unconditionally.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/importAgents_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ]
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ]
                                            }
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type"
                                        ]
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "clearCache"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this clear cache node.",
                                            "type": "string"
                                          },
                                          "config": {
                                            "description": "Optional configuration controlling what is cleared.",
                                            "type": "object",
                                            "properties": {
                                              "clearScope": {
                                                "description": "What to clear. executionCache (default): clears only the decision result cache. all: clears the entire session state including user-defined session variables.",
                                                "type": "string",
                                                "enum": [
                                                  "executionCache",
                                                  "all"
                                                ]
                                              }
                                            }
                                          },
                                          "transition": {
                                            "description": "Optional transitions to continue the flow after clearing cache.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/importAgents_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ]
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ]
                                            }
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type"
                                        ]
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "javascript"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this JavaScript node.",
                                            "type": "string"
                                          },
                                          "outputVar": {
                                            "description": "Variable name to store the returned value for downstream nodes. Downstream templates read it as `{{<outputVar>}}`; transition conditions as `{source:\"vars\", path:\"<outputVar>...\"}`.",
                                            "type": "string"
                                          },
                                          "config": {
                                            "type": "object",
                                            "properties": {
                                              "code": {
                                                "description": "JavaScript source executed in a sandboxed QuickJS interpreter. Written as a function body: it receives ({ vars, evaluation, context, env, input, nodes }) and must `return` a JSON-serializable value. Synchronous only — no network, filesystem, require/import, or timers.",
                                                "type": "string"
                                              },
                                              "timeoutMs": {
                                                "description": "CPU deadline in milliseconds. Default 1000, max 10000.",
                                                "type": "integer",
                                                "minimum": 1,
                                                "maximum": 10000
                                              }
                                            },
                                            "required": [
                                              "code"
                                            ]
                                          },
                                          "transition": {
                                            "description": "Optional transitions to continue the flow after the code runs.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/importAgents_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ]
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ]
                                            }
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type",
                                          "config"
                                        ]
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "forEach"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this forEach node.",
                                            "type": "string"
                                          },
                                          "over": {
                                            "description": "Dotted path to the array to iterate, resolved against the execution scope: top-level workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — for example \"research.socioAlvos\" or \"nodes.build_plan.result.targets\". This is a VALUE PATH, not a Handlebars template: Handlebars renders to a string, so an array passed through it would arrive as \"[object Object]\". A path wrapped in {{ }} is accepted and unwrapped. If the path does not resolve to an array the node fails loudly instead of iterating a string.",
                                            "type": "string"
                                          },
                                          "as": {
                                            "description": "Variable name bound to the current element inside the body node: \"socio\" makes {{socio.nome}} available to the body's templates. Must not be \"iteration\", which is reserved for the {index, total} binding also exposed to the body.",
                                            "type": "string"
                                          },
                                          "each": {
                                            "description": "The body node, referenced by ID. Must be an action, javascript or subAgent node declared in workflow.nodes with no other incoming transitions, and must not be an entry point. Its own \"transition\" array is ignored — the forEach node owns what happens after every item finishes. decision nodes are rejected because the execution cache is keyed by node ID, so parallel instances would contend for one cache entry.",
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the node to run once per item.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "collectInto": {
                                            "description": "Variable name receiving the per-item results array. Each entry is {index, item, ok, value?, grounding?, error?, errorName?}, where \"value\" is whatever the body node's own outputVar would have held (undefined when the body declares none) and \"grounding\" is that item's Google Search queries and sources when the body is a grounded INSTRUCTIONS node — the same shape a standalone node exposes as nodes.<id>.grounding. Entries stay aligned with the source array by index, including failed items, so a downstream node can tell \"this item returned nothing\" apart from \"this item was never tried\". Omit only if nothing downstream needs the results.",
                                            "type": "string"
                                          },
                                          "maxConcurrency": {
                                            "description": "How many items run at once. Defaults to 5. Raise carefully: per-item parallelism hits provider rate limits well before it hits platform limits.",
                                            "type": "integer",
                                            "minimum": 1,
                                            "maximum": 20
                                          },
                                          "transition": {
                                            "description": "Transitions to continue the flow after every item has finished.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/importAgents_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ]
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ]
                                            }
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type",
                                          "over",
                                          "as",
                                          "each"
                                        ]
                                      }
                                    ]
                                  }
                                }
                              },
                              "required": [
                                "toolName",
                                "toolDescription",
                                "entryPoints",
                                "nodes"
                              ]
                            },
                            "tools": {
                              "deprecated": true,
                              "description": "Deprecated and ignored. Tool availability is configured by the application, not the agent spec.",
                              "type": "array",
                              "items": {}
                            },
                            "metadata": {
                              "description": "Arbitrary metadata for custom extensions. Not used by the execution engine.",
                              "type": "object",
                              "propertyNames": {
                                "type": "string"
                              },
                              "additionalProperties": {}
                            }
                          },
                          "required": [
                            "version",
                            "name",
                            "prompt",
                            "workflow"
                          ]
                        },
                        "evals": {
                          "default": [],
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string",
                                "minLength": 1
                              },
                              "description": {
                                "anyOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "scheduler": {
                                "anyOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "evalSpec": {},
                              "enabled": {
                                "type": "boolean"
                              },
                              "selfImproveEnabled": {
                                "type": "boolean"
                              },
                              "selfImproveTargetScore": {
                                "anyOf": [
                                  {
                                    "type": "number"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "selfImproveMaxIterations": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991
                              },
                              "folderPath": {
                                "description": "Materialized '/'-separated folder path of the eval (e.g. 'Regressão/Checkout'), or null for root.",
                                "anyOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "tags": {
                                "description": "Free-form labels of the eval.",
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "metadata": {
                                "description": "Free-form data of the eval, including the `sources` conversations it was built from.",
                                "anyOf": [
                                  {
                                    "description": "Free-form data recorded on the eval. Provenance belongs under `sources`, a list whose entries have documented keys so every writer points at the originating conversations the same way. An eval drawn from a single conversation carries a one-element list.",
                                    "type": "object",
                                    "properties": {
                                      "sources": {
                                        "description": "The conversations the eval was built from, most relevant first.",
                                        "maxItems": 25,
                                        "type": "array",
                                        "items": {
                                          "type": "object",
                                          "properties": {
                                            "threadId": {
                                              "description": "Id of the thread the eval was built from.",
                                              "examples": [
                                                "cmc3k5r2b0004l608w1t8fmz9"
                                              ],
                                              "type": "string",
                                              "minLength": 1,
                                              "maxLength": 255
                                            },
                                            "executionId": {
                                              "description": "Id of the agent execution the eval was built from.",
                                              "examples": [
                                                "exec_01j9z3k2b4c5"
                                              ],
                                              "type": "string",
                                              "minLength": 1,
                                              "maxLength": 255
                                            },
                                            "messageId": {
                                              "description": "Id of the specific message the eval was built from.",
                                              "examples": [
                                                "cmc3k9p7f0007"
                                              ],
                                              "type": "string",
                                              "minLength": 1,
                                              "maxLength": 255
                                            },
                                            "url": {
                                              "description": "Link to the source conversation. Must be an absolute http(s) URL.",
                                              "examples": [
                                                "https://platform.docana.com/application/42/agents/a1/logs?search=thread-1"
                                              ],
                                              "type": "string",
                                              "minLength": 1,
                                              "maxLength": 2048
                                            },
                                            "label": {
                                              "description": "Human friendly name of the source conversation.",
                                              "examples": [
                                                "WhatsApp 5511 — 12/08"
                                              ],
                                              "type": "string",
                                              "minLength": 1,
                                              "maxLength": 255
                                            },
                                            "capturedAt": {
                                              "description": "ISO 8601 timestamp of when the eval was captured.",
                                              "examples": [
                                                "2026-08-17T12:00:00.000Z"
                                              ],
                                              "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))$"
                                            }
                                          },
                                          "additionalProperties": {}
                                        }
                                      }
                                    },
                                    "additionalProperties": {}
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              }
                            },
                            "required": [
                              "name",
                              "evalSpec"
                            ]
                          }
                        },
                        "routines": {
                          "default": [],
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string",
                                "minLength": 1
                              },
                              "prompt": {
                                "type": "string"
                              },
                              "enabled": {
                                "default": true,
                                "type": "boolean"
                              },
                              "metadata": {
                                "anyOf": [
                                  {
                                    "type": "object",
                                    "propertyNames": {
                                      "type": "string"
                                    },
                                    "additionalProperties": {}
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "triggers": {
                                "default": [],
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "type": {
                                      "type": "string",
                                      "enum": [
                                        "SCHEDULED",
                                        "API",
                                        "DOCUMENT_EVENT"
                                      ]
                                    },
                                    "enabled": {
                                      "default": true,
                                      "type": "boolean"
                                    },
                                    "cronExpression": {
                                      "anyOf": [
                                        {
                                          "type": "string"
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    },
                                    "collectionIds": {
                                      "default": [],
                                      "type": "array",
                                      "items": {
                                        "type": "integer",
                                        "minimum": -9007199254740991,
                                        "maximum": 9007199254740991
                                      }
                                    },
                                    "eventName": {
                                      "anyOf": [
                                        {
                                          "type": "string"
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    },
                                    "metadata": {
                                      "type": "object",
                                      "propertyNames": {
                                        "type": "string"
                                      },
                                      "additionalProperties": {}
                                    }
                                  },
                                  "required": [
                                    "type"
                                  ]
                                }
                              }
                            },
                            "required": [
                              "name",
                              "prompt"
                            ]
                          }
                        },
                        "insights": {
                          "anyOf": [
                            {
                              "type": "object",
                              "properties": {
                                "enabled": {
                                  "description": "Master kill switch for this agent's insights. When false, no extraction runs anywhere (the post-execution hook is suppressed and the archive API rejects summarize=true) and no prior insights are injected into new conversations.",
                                  "type": "boolean"
                                },
                                "shareWithPastConversations": {
                                  "description": "When true (and `enabled` is true), inject summaries from this user's past archived conversations in the same application into LLM calls that consume conversation history (instruction nodes; decision criteria with EvaluationParams.CONTEXT). Defaults to false.",
                                  "type": "boolean"
                                },
                                "summaryMode": {
                                  "description": "When to extract insights for this agent. \"afterExecution\" (default) runs archive + extraction after every successful agent turn (with or without an End node), so channels like WhatsApp keep producing insights. \"onArchive\" skips the automatic hook; insights are only extracted when the archive API is called with summarize=true.",
                                  "type": "string",
                                  "enum": [
                                    "afterExecution",
                                    "onArchive"
                                  ]
                                },
                                "summaryConfig": {
                                  "description": "Config used when this agent extracts a new summary (End-node generateInsights or archive API with summarize=true).",
                                  "type": "object",
                                  "properties": {
                                    "summaryLength": {
                                      "description": "Target length of the generated summary.",
                                      "type": "string",
                                      "enum": [
                                        "short",
                                        "medium",
                                        "detailed"
                                      ]
                                    },
                                    "customPrompt": {
                                      "description": "Optional extra guidance appended to the summarizer system prompt.",
                                      "type": "string"
                                    },
                                    "historyMessageLimit": {
                                      "description": "Cap on the number of recent messages included when generating the summary. Omitted = no cap.",
                                      "type": "integer",
                                      "exclusiveMinimum": 0,
                                      "maximum": 9007199254740991
                                    },
                                    "maxSummaryChars": {
                                      "description": "Optional cap on the persisted summary length (characters).",
                                      "type": "integer",
                                      "exclusiveMinimum": 0,
                                      "maximum": 9007199254740991
                                    }
                                  }
                                },
                                "frequency": {
                                  "description": "How often insights are extracted. \"onEnd\" (default) extracts once when the conversation is archived. \"everyTurn\" extracts after every message — the legacy behaviour, which costs roughly O(N^2) tokens over an N-turn conversation. When absent, the legacy `summaryMode` is used: \"afterExecution\" maps to \"everyTurn\", anything else maps to \"onEnd\". Any other stored value (e.g. a removed legacy mode) resolves to \"onEnd\", the cheap option.",
                                  "type": "string",
                                  "enum": [
                                    "onEnd",
                                    "everyTurn"
                                  ]
                                },
                                "samplingRate": {
                                  "description": "Share of conversations that produce insights automatically, 0..1. Defaults to 1 (all). The decision is a deterministic hash of (agentId, threadId), so a conversation is either sampled for its whole life or not at all. Explicit archive calls and on-demand generation always run regardless of this rate.",
                                  "type": "number",
                                  "minimum": 0,
                                  "maximum": 1
                                },
                                "dataPoints": {
                                  "description": "Structured data points to extract from the conversation when generating insights.",
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "id": {
                                        "description": "Stable identifier for the data point; reused across saves so snapshot history and aggregations stay correlated over time.",
                                        "type": "string"
                                      },
                                      "name": {
                                        "description": "Human-readable name of the data point (displayed in the UI).",
                                        "type": "string"
                                      },
                                      "description": {
                                        "description": "Instruction describing what this data point should capture from the conversation.",
                                        "type": "string"
                                      },
                                      "type": {
                                        "description": "The expected type of the extracted value.",
                                        "type": "string",
                                        "enum": [
                                          "string",
                                          "number",
                                          "boolean"
                                        ]
                                      }
                                    },
                                    "required": [
                                      "id",
                                      "name",
                                      "description",
                                      "type"
                                    ]
                                  }
                                }
                              },
                              "required": [
                                "enabled"
                              ]
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "evalMockBaseline": {
                          "anyOf": [
                            {
                              "type": "object",
                              "propertyNames": {
                                "type": "string"
                              },
                              "additionalProperties": {
                                "anyOf": [
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "examples": [
                                          "webhook"
                                        ],
                                        "type": "string",
                                        "const": "webhook"
                                      },
                                      "mode": {
                                        "default": "staticResponse",
                                        "type": "string",
                                        "const": "staticResponse"
                                      },
                                      "response": {
                                        "anyOf": [
                                          {
                                            "type": "object",
                                            "properties": {
                                              "status": {
                                                "examples": [
                                                  200
                                                ],
                                                "type": "integer",
                                                "minimum": 100,
                                                "maximum": 599
                                              },
                                              "headers": {
                                                "examples": [
                                                  {
                                                    "content-type": "application/json"
                                                  }
                                                ],
                                                "type": "object",
                                                "propertyNames": {
                                                  "type": "string"
                                                },
                                                "additionalProperties": {
                                                  "type": "string"
                                                }
                                              },
                                              "body": {
                                                "examples": [
                                                  {
                                                    "orderStatus": "shipped"
                                                  }
                                                ],
                                                "$ref": "#/components/schemas/importAgents_schema1"
                                              },
                                              "noResponse": {
                                                "not": {}
                                              }
                                            },
                                            "required": [
                                              "status"
                                            ]
                                          },
                                          {
                                            "type": "object",
                                            "properties": {
                                              "noResponse": {
                                                "examples": [
                                                  true
                                                ],
                                                "type": "boolean",
                                                "const": true
                                              },
                                              "error": {
                                                "examples": [
                                                  "connect ECONNREFUSED 10.0.0.4:443"
                                                ],
                                                "type": "string"
                                              },
                                              "status": {
                                                "not": {}
                                              }
                                            },
                                            "required": [
                                              "noResponse"
                                            ]
                                          }
                                        ]
                                      }
                                    },
                                    "required": [
                                      "type",
                                      "response"
                                    ]
                                  },
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "examples": [
                                          "webhook"
                                        ],
                                        "type": "string",
                                        "const": "webhook"
                                      },
                                      "mode": {
                                        "type": "string",
                                        "const": "sequence"
                                      },
                                      "responses": {
                                        "examples": [
                                          [
                                            {
                                              "status": 400,
                                              "body": {
                                                "error": "CEP inválido"
                                              }
                                            },
                                            {
                                              "status": 201,
                                              "body": {
                                                "data": {
                                                  "status": "AUTORIZADA"
                                                }
                                              }
                                            }
                                          ]
                                        ],
                                        "minItems": 1,
                                        "type": "array",
                                        "items": {
                                          "anyOf": [
                                            {
                                              "type": "object",
                                              "properties": {
                                                "status": {
                                                  "examples": [
                                                    200
                                                  ],
                                                  "type": "integer",
                                                  "minimum": 100,
                                                  "maximum": 599
                                                },
                                                "headers": {
                                                  "examples": [
                                                    {
                                                      "content-type": "application/json"
                                                    }
                                                  ],
                                                  "type": "object",
                                                  "propertyNames": {
                                                    "type": "string"
                                                  },
                                                  "additionalProperties": {
                                                    "type": "string"
                                                  }
                                                },
                                                "body": {
                                                  "examples": [
                                                    {
                                                      "orderStatus": "shipped"
                                                    }
                                                  ],
                                                  "$ref": "#/components/schemas/importAgents_schema1"
                                                },
                                                "noResponse": {
                                                  "not": {}
                                                }
                                              },
                                              "required": [
                                                "status"
                                              ]
                                            },
                                            {
                                              "type": "object",
                                              "properties": {
                                                "noResponse": {
                                                  "examples": [
                                                    true
                                                  ],
                                                  "type": "boolean",
                                                  "const": true
                                                },
                                                "error": {
                                                  "examples": [
                                                    "connect ECONNREFUSED 10.0.0.4:443"
                                                  ],
                                                  "type": "string"
                                                },
                                                "status": {
                                                  "not": {}
                                                }
                                              },
                                              "required": [
                                                "noResponse"
                                              ]
                                            }
                                          ]
                                        }
                                      }
                                    },
                                    "required": [
                                      "type",
                                      "mode",
                                      "responses"
                                    ]
                                  }
                                ]
                              }
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "spec"
                      ]
                    }
                  },
                  "applicationId": {
                    "description": "Target application id.",
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  }
                },
                "required": [
                  "exportVersion",
                  "agent"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Import summary with the created root agent id",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "description": "True when the whole bundle was imported successfully.",
                      "type": "boolean"
                    },
                    "rootAgentId": {
                      "description": "Id of the bundle's root agent as created or updated in the target application.",
                      "examples": [
                        "cmc4v8xq10001l708h2vxk9d3"
                      ],
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "createdCount": {
                      "description": "Number of agents created or updated by the import, counting the root agent and its sub-agents.",
                      "examples": [
                        3
                      ],
                      "type": "number"
                    }
                  },
                  "required": [
                    "ok",
                    "rootAgentId",
                    "createdCount"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid payload, missing applicationId or cyclic dependencies",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Import failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/import/check/": {
      "post": {
        "operationId": "checkAgentImport",
        "summary": "Check whether agents of an import bundle already exist",
        "tags": [
          "agents"
        ],
        "description": "Inspects an export bundle and reports whether the root agent and its sub-agents already exist in the target application. Accepts `application/json` or `multipart/form-data` with a `file` field. `applicationId` may be supplied in the body or query string; it is required only when neither location supplies it. When both are supplied, the body value wins — the same precedence as the import endpoint.",
        "parameters": [
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Target application id. A body value takes precedence when both are supplied.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "The exported agent bundle to check. Also accepted as `multipart/form-data` with the bundle JSON in a `file` field and an optional `applicationId` field. `applicationId` may instead be supplied in the query string; when both are supplied, the body value wins.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "exportVersion": {
                    "type": "number",
                    "minimum": 1
                  },
                  "agent": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "sourceId": {
                        "description": "The id this entry had in the bundle, when `id` points at an agent that already exists in the target application. Stored as the imported agent's origin so a later import of the same bundle still recognizes it.",
                        "type": "string"
                      },
                      "name": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "description": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "spec": {
                        "type": "object",
                        "properties": {
                          "version": {
                            "description": "Schema version. Must be \"2.0\".",
                            "type": "string",
                            "const": "2.0"
                          },
                          "id": {
                            "description": "Unique identifier for this agent. Auto-generated if not provided.",
                            "type": "string"
                          },
                          "name": {
                            "description": "Human-readable name of the agent.",
                            "type": "string"
                          },
                          "prompt": {
                            "description": "System instructions for the agent. Can be a single string or an array of strings joined at runtime.",
                            "anyOf": [
                              {
                                "type": "string",
                                "minLength": 1
                              },
                              {
                                "minItems": 1,
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1
                                }
                              }
                            ]
                          },
                          "llm": {
                            "description": "LLM configuration for the router persona. Optional; uses platform defaults when omitted.",
                            "type": "object",
                            "properties": {
                              "provider": {
                                "description": "The LLM provider identifier (e.g., \"google\", \"openai\").",
                                "type": "string"
                              },
                              "model": {
                                "description": "The model name to use (e.g., \"gemini-2.0-flash\").",
                                "type": "string"
                              },
                              "temperature": {
                                "description": "Sampling temperature (0-2). IGNORED on Gemini 3.x models, which Google deprecated this parameter for on 2026-07-21 — it is accepted and silently discarded, so it no longer makes output more deterministic. Still accepted for older models and for backwards compatibility with existing specs.",
                                "type": "number"
                              },
                              "maxOutputTokens": {
                                "description": "Maximum number of tokens the model can generate.",
                                "type": "number"
                              },
                              "toolChoice": {
                                "description": "Controls how the model uses tools: auto (model decides), required (must use a tool), none (no tools).",
                                "type": "string",
                                "enum": [
                                  "auto",
                                  "required",
                                  "none"
                                ]
                              },
                              "jsonMode": {
                                "description": "If true, the model outputs valid JSON.",
                                "type": "boolean"
                              }
                            },
                            "required": [
                              "provider",
                              "model"
                            ]
                          },
                          "inlineEvaluationCriteria": {
                            "description": "Map of criteria ID to its full definition. Decision nodes reference these by key. These are criteria that have not been persisted to the database yet. During sandbox execution, they are loaded into memory. During publish, they are persisted to the database and this field is cleared.",
                            "type": "object",
                            "propertyNames": {
                              "type": "string"
                            },
                            "additionalProperties": {
                              "type": "object",
                              "properties": {
                                "name": {
                                  "description": "Human-readable name of this evaluation criteria. MUST be a non-empty short noun phrase (e.g. \"Real-Estate Availability Intent\"). Empty strings are forbidden.",
                                  "type": "string"
                                },
                                "type": {
                                  "description": "The evaluation criteria type (e.g., CUSTOM, QUALITY_HELPFULNESS).",
                                  "type": "string",
                                  "enum": [
                                    "QUALITY_ENGAGINGNESS",
                                    "QUALITY_COHERENCE",
                                    "QUALITY_CONSISTENCY",
                                    "QUALITY_FLUENCY",
                                    "QUALITY_RELEVANCE",
                                    "SECURITY_FINANCIAL_DETECTION",
                                    "SECURITY_PII_DETECTION",
                                    "SECURITY_ANOMALOUS_CONVERSATION",
                                    "PERSONALITY_EXTRAVERSION",
                                    "PERSONALITY_OPEN_TO_EXPERIENCE",
                                    "PERSONALITY_CONSCIENTIOUSNESS",
                                    "PERSONALITY_AGREEABLENESS",
                                    "PERSONALITY_NEUROTICISM",
                                    "PERSONALITY_OTHER",
                                    "DOCUMENT_INSIGHTS",
                                    "CUSTOM"
                                  ]
                                },
                                "evaluationCriteria": {
                                  "description": "REQUIRED non-empty instruction the evaluator follows to assess the input. One or two sentences in plain language: what to assess, and (if structuredDataParams is set) how to populate each declared field. Example: \"Decide whether the user is asking about real-estate availability. Set isAvailability to true only when the user is clearly asking whether a property is available; otherwise false.\" Empty strings, null, or omission make the reasoning useless and are forbidden.",
                                  "type": "string"
                                },
                                "evaluationSteps": {
                                  "description": "Ordered evaluation steps for the criteria.",
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "evaluationParams": {
                                  "description": "Parameters used during evaluation (e.g., INPUT, CONTEXT).",
                                  "type": "array",
                                  "items": {
                                    "type": "string",
                                    "enum": [
                                      "INPUT",
                                      "ACTUAL_OUTPUT",
                                      "EXPECTED_OUTPUT",
                                      "CONTEXT",
                                      "RETRIEVAL_CONTEXT",
                                      "EXECUTION_CONTEXT"
                                    ]
                                  }
                                },
                                "structuredDataParams": {
                                  "description": "Map of field name to a natural-language description of what to extract. The description should encode both the type and the legal values, e.g. \"true if the user is asking about real-estate availability, false otherwise\" (boolean), \"one of: AVAILABILITY, PRICING, CONTACT, OTHER\" (enum), or \"numeric score 1-5 reflecting urgency\" (number). Each declared field becomes a routing key accessible from transition conditions as \"evaluation.structuredData.<field>\" (and is also flattened into top-level vars for action templates). Prefer this for routing on what the user meant or asked; use scores.mean for confidence/quality routing.",
                                  "anyOf": [
                                    {
                                      "type": "object",
                                      "propertyNames": {
                                        "type": "string"
                                      },
                                      "additionalProperties": {}
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                },
                                "metadata": {
                                  "description": "Additional metadata for the criteria.",
                                  "anyOf": [
                                    {
                                      "type": "object",
                                      "propertyNames": {
                                        "type": "string"
                                      },
                                      "additionalProperties": {}
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                },
                                "enabled": {
                                  "description": "Whether this criteria is enabled. Defaults to true.",
                                  "type": "boolean"
                                }
                              },
                              "required": [
                                "name",
                                "type",
                                "evaluationCriteria"
                              ]
                            }
                          },
                          "workflow": {
                            "description": "The workflow definition including entry points and execution nodes.",
                            "type": "object",
                            "properties": {
                              "toolName": {
                                "description": "The tool name used to invoke this agent in the workflow.",
                                "type": "string"
                              },
                              "toolDescription": {
                                "description": "A description of what this agent does, shown to the LLM router.",
                                "type": "string"
                              },
                              "executionTimeoutSeconds": {
                                "description": "Wall-clock ceiling for ONE execution of this workflow, in seconds (30-1800). When the deadline passes the run is aborted — in-flight model calls are cancelled, sub-agents included — and the execution finishes with status TIMED_OUT, with the reason recorded on the nodes that were cut. Optional: an agent that declares nothing keeps the platform behavior (no explicit ceiling). Declare it when the agent legitimately runs for minutes (deep research, long tool chains) so a slow run is never mistaken for a hung one, or when it must never occupy a worker past a known bound. The budget is per attempt: a run resumed after a crash starts a fresh timer.",
                                "type": "integer",
                                "minimum": 30,
                                "maximum": 1800
                              },
                              "entryPoints": {
                                "description": "Entry points into the workflow. MUST contain at least one node ID; an empty array makes the workflow non-executable. When you restructure or rename the first node, update this list in the same operation so it points at the new entry node.",
                                "minItems": 1,
                                "type": "array",
                                "items": {
                                  "anyOf": [
                                    {
                                      "description": "Node ID to use as an unconditional entry point.",
                                      "type": "string"
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "nodeId": {
                                          "description": "The ID of the entry point node.",
                                          "type": "string"
                                        },
                                        "if": {
                                          "description": "Optional condition that must be met for this entry point to activate.",
                                          "$ref": "#/components/schemas/checkAgentImport_schema0"
                                        }
                                      },
                                      "required": [
                                        "nodeId"
                                      ]
                                    }
                                  ]
                                }
                              },
                              "nodes": {
                                "description": "The workflow nodes: decision, action, subAgent, end, state, hub, jump, clearCache, javascript, or forEach.",
                                "type": "array",
                                "items": {
                                  "anyOf": [
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "decision"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this decision node.",
                                          "type": "string"
                                        },
                                        "evaluationCriteria": {
                                          "description": "Evaluation criteria IDs (string references) or inline criteria objects.",
                                          "type": "array",
                                          "items": {
                                            "anyOf": [
                                              {
                                                "type": "string"
                                              },
                                              {
                                                "type": "object",
                                                "properties": {
                                                  "id": {
                                                    "type": "string"
                                                  },
                                                  "name": {
                                                    "description": "Required non-empty short human-readable name for this criterion (e.g. \"Real-Estate Availability Intent\"). Never an empty string.",
                                                    "type": "string"
                                                  },
                                                  "type": {
                                                    "type": "string",
                                                    "enum": [
                                                      "QUALITY_ENGAGINGNESS",
                                                      "QUALITY_COHERENCE",
                                                      "QUALITY_CONSISTENCY",
                                                      "QUALITY_FLUENCY",
                                                      "QUALITY_RELEVANCE",
                                                      "SECURITY_FINANCIAL_DETECTION",
                                                      "SECURITY_PII_DETECTION",
                                                      "SECURITY_ANOMALOUS_CONVERSATION",
                                                      "PERSONALITY_EXTRAVERSION",
                                                      "PERSONALITY_OPEN_TO_EXPERIENCE",
                                                      "PERSONALITY_CONSCIENTIOUSNESS",
                                                      "PERSONALITY_AGREEABLENESS",
                                                      "PERSONALITY_NEUROTICISM",
                                                      "PERSONALITY_OTHER",
                                                      "DOCUMENT_INSIGHTS",
                                                      "CUSTOM"
                                                    ]
                                                  },
                                                  "evaluationCriteria": {
                                                    "description": "REQUIRED non-empty instruction telling the evaluator what to assess. One or two sentences in plain language: what to evaluate, and — when structuredDataParams is set — how to populate each declared field. Empty strings, null, or omission are forbidden; an empty description leaves the reasoning useless. Example: \"Decide whether the user is asking about real-estate availability. Set isAvailability to true only when the user is clearly asking whether a property is available; otherwise false.\"",
                                                    "type": "string"
                                                  },
                                                  "evaluationSteps": {
                                                    "type": "array",
                                                    "items": {
                                                      "type": "string"
                                                    }
                                                  },
                                                  "structuredDataParams": {
                                                    "anyOf": [
                                                      {
                                                        "type": "object",
                                                        "propertyNames": {
                                                          "type": "string"
                                                        },
                                                        "additionalProperties": {}
                                                      },
                                                      {
                                                        "type": "null"
                                                      }
                                                    ]
                                                  },
                                                  "metadata": {
                                                    "anyOf": [
                                                      {
                                                        "type": "object",
                                                        "propertyNames": {
                                                          "type": "string"
                                                        },
                                                        "additionalProperties": {}
                                                      },
                                                      {
                                                        "type": "null"
                                                      }
                                                    ]
                                                  },
                                                  "enabled": {
                                                    "type": "boolean"
                                                  },
                                                  "applicationId": {
                                                    "type": "number"
                                                  },
                                                  "evaluationParams": {
                                                    "type": "array",
                                                    "items": {
                                                      "type": "string",
                                                      "enum": [
                                                        "INPUT",
                                                        "ACTUAL_OUTPUT",
                                                        "EXPECTED_OUTPUT",
                                                        "CONTEXT",
                                                        "RETRIEVAL_CONTEXT",
                                                        "EXECUTION_CONTEXT"
                                                      ]
                                                    }
                                                  }
                                                },
                                                "required": [
                                                  "name",
                                                  "type",
                                                  "evaluationCriteria"
                                                ]
                                              }
                                            ]
                                          }
                                        },
                                        "transition": {
                                          "description": "Transitions to other nodes based on evaluation results.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/checkAgentImport_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        },
                                        "cachePolicy": {
                                          "description": "Controls execution caching for this decision node across messages in a conversation. auto (default): cache result and use a lightweight guard evaluation to detect staleness. always: always use cached result until explicitly cleared. never: always re-evaluate all criteria every message (disables caching).",
                                          "type": "string",
                                          "enum": [
                                            "auto",
                                            "always",
                                            "never"
                                          ]
                                        },
                                        "selectionPolicy": {
                                          "description": "Controls which enabled criteria are evaluated each message. all (default): every enabled criterion runs. contextual: a lightweight router selects only the criteria relevant to the current input and conversation state; the rest are skipped. Skipped criteria are not evaluated, so their structuredData fields are absent downstream (route on them with the \"exists\"/\"notExists\" operators) and scores.mean reflects only the criteria that ran.",
                                          "type": "string",
                                          "enum": [
                                            "all",
                                            "contextual"
                                          ]
                                        },
                                        "alwaysRunCriteria": {
                                          "description": "Only used when selectionPolicy is \"contextual\": IDs of evaluation criteria that always run (they bypass the router); every other criterion is AI-selected per message. Use this to pin extractors whose structuredData a downstream node depends on. Ignored when selectionPolicy is \"all\".",
                                          "type": "array",
                                          "items": {
                                            "type": "string"
                                          }
                                        },
                                        "contextualSelectionPrompt": {
                                          "description": "Only used when selectionPolicy is \"contextual\": extra author guidance appended to the built-in router prompt to steer which criteria it picks (e.g. \"prefer running Consultar NFSe whenever the user mentions a nota fiscal, even indirectly\"). It augments the router — it does not replace its output contract or the safe fallback of running everything. Ignored when selectionPolicy is \"all\".",
                                          "type": "string"
                                        },
                                        "routingPolicy": {
                                          "description": "How many REASONINGS (criteria) may win the routing on this node per message. all (default): every matching conditional transition fires in parallel. bestReasoning: only the highest-scoring reasoning wins — ALL matched transitions whose condition is anchored on it fire (they are that reasoning's flow), everything anchored on other reasonings is suppressed. topReasonings: like bestReasoning but the best `maxReasonings` reasonings win. A matched transition is anchored on the highest-scoring criterion its condition references (via \"resultsById.<id>.score\" paths, at any nesting). Score ties between reasonings break by position in this node's evaluationCriteria list (earlier wins) — reorder the list to set priority. Matched transitions that reference NO criterion score (pure structuredData/context/state conditions) are outside the competition and always fire, like \"default\" and unconditional transitions. Criteria evaluation is unaffected — this arbitrates AFTER scoring, so it is the reliable way to get \"only one reasoning wins\" (independent per-criterion evaluations cannot be prompted into exclusivity).",
                                          "type": "string",
                                          "enum": [
                                            "all",
                                            "bestReasoning",
                                            "topReasonings"
                                          ]
                                        },
                                        "maxReasonings": {
                                          "description": "Only used when routingPolicy is \"topReasonings\": how many of the highest-scoring reasonings win the routing. Ignored for other policies (\"bestReasoning\" is exactly maxReasonings = 1).",
                                          "type": "integer",
                                          "minimum": 1,
                                          "maximum": 9007199254740991
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "evaluationCriteria",
                                        "transition"
                                      ]
                                    },
                                    {
                                      "oneOf": [
                                        {
                                          "type": "object",
                                          "properties": {
                                            "id": {
                                              "description": "Unique identifier for this node.",
                                              "type": "string"
                                            },
                                            "type": {
                                              "type": "string",
                                              "const": "action"
                                            },
                                            "label": {
                                              "description": "Human-readable label for this action node.",
                                              "type": "string"
                                            },
                                            "mode": {
                                              "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                              "type": "string",
                                              "enum": [
                                                "sync",
                                                "async"
                                              ]
                                            },
                                            "outputVar": {
                                              "description": "Variable name to store the action output for use by downstream nodes.",
                                              "type": "string"
                                            },
                                            "transition": {
                                              "description": "Transitions to other nodes after this action completes.",
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "if": {
                                                    "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                    "$ref": "#/components/schemas/checkAgentImport_schema0"
                                                  },
                                                  "default": {
                                                    "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                    "type": "boolean"
                                                  },
                                                  "to": {
                                                    "type": "object",
                                                    "properties": {
                                                      "nodeId": {
                                                        "description": "The ID of the target node to transition to.",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "nodeId"
                                                    ]
                                                  },
                                                  "stop": {
                                                    "description": "If true, stop execution after this transition.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "to"
                                                ]
                                              }
                                            },
                                            "actionType": {
                                              "type": "string",
                                              "const": "INSTRUCTIONS"
                                            },
                                            "config": {
                                              "type": "object",
                                              "properties": {
                                                "instructions": {
                                                  "description": "The instructions for the LLM to execute.",
                                                  "type": "string"
                                                },
                                                "modelTier": {
                                                  "description": "The model tier to use for this instruction. Defaults to regular.",
                                                  "type": "string",
                                                  "enum": [
                                                    "lite",
                                                    "regular",
                                                    "pro"
                                                  ]
                                                },
                                                "thinkingEffortPct": {
                                                  "description": "Thinking effort percentage (0-100) controlling how much reasoning the model applies.",
                                                  "type": "number",
                                                  "minimum": 0,
                                                  "maximum": 100
                                                },
                                                "maxOutputTokens": {
                                                  "description": "Maximum tokens the model may generate for this node. On thinking models the budget is SHARED between reasoning and output — reasoning routinely consumes most of it — so a node whose structured output is truncated is usually better served by lowering thinkingEffortPct than by raising this. Defaults to the model maximum when omitted.",
                                                  "type": "integer",
                                                  "minimum": 1,
                                                  "maximum": 9007199254740991
                                                },
                                                "maxRetries": {
                                                  "description": "How many times this node retries a failed model call. Defaults to 2 when the node has an outputSchema and 5 otherwise. Raise it for nodes whose long outputs are exposed to dropped provider streams; it does not help failures the model reproduces deterministically.",
                                                  "type": "integer",
                                                  "minimum": 1,
                                                  "maximum": 10
                                                },
                                                "toolChoiceMode": {
                                                  "description": "Tool selection mode for this instruction. Defaults to auto when omitted.",
                                                  "type": "string",
                                                  "enum": [
                                                    "auto",
                                                    "none",
                                                    "tool",
                                                    "tools"
                                                  ]
                                                },
                                                "toolChoiceToolName": {
                                                  "description": "When toolChoiceMode is \"tool\", the specific tool name to force.",
                                                  "type": "string"
                                                },
                                                "toolChoiceToolNames": {
                                                  "description": "When toolChoiceMode is \"tools\", the list of allowed tool names.",
                                                  "type": "array",
                                                  "items": {
                                                    "type": "string"
                                                  }
                                                },
                                                "suppressTextResponse": {
                                                  "description": "When true, text output from the LLM is suppressed and only tool-call results are emitted. Useful when the instruction should only invoke tools (e.g., displayMedia) without generating follow-up text.",
                                                  "type": "boolean"
                                                },
                                                "stopAfterFirstToolCall": {
                                                  "description": "When true and a single tool is forced with text suppressed, the instruction stops after the first successful tool call. Defaults to false, which allows the tool to be called across multiple steps.",
                                                  "type": "boolean"
                                                },
                                                "internal": {
                                                  "description": "When true, this node is an intermediate step: its text/structured output is NOT shown to the user (not streamed, not persisted as a visible message part) and is only captured into the node's outputVar for downstream nodes. Reasoning and tool-call activity chips remain visible. Use for internal hand-offs (e.g. tool-driven data synthesis a later node consumes); the user-facing reply should come from a later, non-internal node.",
                                                  "type": "boolean"
                                                },
                                                "outputSchema": {
                                                  "description": "JSON Schema for structured output. When provided, the LLM will output valid JSON matching this schema instead of free-form text.",
                                                  "type": "object",
                                                  "properties": {
                                                    "type": {
                                                      "description": "JSON Schema type, must be \"object\" for structured output.",
                                                      "type": "string",
                                                      "const": "object"
                                                    },
                                                    "properties": {
                                                      "description": "Schema properties defining the expected output structure.",
                                                      "type": "object",
                                                      "propertyNames": {
                                                        "type": "string"
                                                      },
                                                      "additionalProperties": {}
                                                    },
                                                    "required": {
                                                      "description": "Array of required property names.",
                                                      "type": "array",
                                                      "items": {
                                                        "type": "string"
                                                      }
                                                    },
                                                    "additionalProperties": {
                                                      "description": "Whether to allow additional properties not defined in the schema.",
                                                      "type": "boolean"
                                                    },
                                                    "description": {
                                                      "description": "Description of the expected output to guide the LLM.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "type",
                                                    "properties"
                                                  ]
                                                },
                                                "grounding": {
                                                  "description": "Model-side grounding for this node. Only Google Search is available today.",
                                                  "type": "object",
                                                  "properties": {
                                                    "googleSearch": {
                                                      "description": "Enable Google Search grounding: the model searches the public web (via Gemini's built-in google_search tool) while executing this instruction and answers from what it finds. Set `{}` to enable with defaults. The node result then carries `grounding` — the queries Google ran and the sources it cited, each with the resolved article URL, its domain and the passages of the reply it supports — readable downstream as `nodes.<nodeId>.grounding` in javascript nodes and templates; the text/JSON reply itself still flows through outputVar as usual. With an outputSchema the search runs first and the JSON is synthesized afterwards with the numbered source list, so declare a `sourceIds` or `url` field if you want citations inside the structured output. Incompatible with toolChoiceMode \"tool\" and with suppressTextResponse (a forced tool call and Google Search in one request returns an empty reply); with toolChoiceMode \"none\" the node still searches but calls no other tool. Each prompt costs Google one search query per query the model decides to run (usually 4–10), billed per query beyond the project's free tier.",
                                                      "type": "object",
                                                      "properties": {
                                                        "excludeDomains": {
                                                          "description": "Domains Google Search must not ground on, e.g. [\"youtube.com\", \"reddit.com\"]. A domain excludes its subdomains too.",
                                                          "type": "array",
                                                          "items": {
                                                            "type": "string"
                                                          }
                                                        }
                                                      }
                                                    }
                                                  }
                                                },
                                                "urlContext": {
                                                  "description": "Gemini URL context: hand the model a list of URLs to READ IN FULL server-side instead of fetching their text into a variable first. The URLs come from the fixed \"urls\" list, from the \"from\" value path, or from both (fixed first). They are appended to the end of the instruction and the provider fetches and reads the pages inside the same call. With an outputSchema the node runs as a SINGLE call (reading and synthesis must share it), so pair it with toolChoiceMode \"none\" unless the node truly needs function tools. Limits: 20 URLs per call (extra ones are dropped and reported as `truncated`), public pages only — paywalls, Google News redirect links and private hosts fail. The model may skip fetching when the URLs sit inside a very long prompt, so prefer a dedicated short reading node over bolting URLs onto a large synthesis prompt. The node output carries `urlContext.{requested,retrieved,unread,truncated,invalid,unresolved,supported,tokens}`. `unread` is the integrity signal — it lists every URL the model did not read, including the ones dropped by the 20-URL cap — so branch on `nodes.<id>.urlContext.unread` for a fallback reader (inside a forEach body it holds only the last item). `unresolved` says the \"from\" path resolved to nothing, `invalid` lists entries that were not http(s) URLs, and `supported` is false when the model could not carry the tool: in those cases nothing was read at all. Retrieved page content is billed as input tokens and added to the node usage as `urlContextTokens`. Gemini 3+ models only.",
                                                  "type": "object",
                                                  "properties": {
                                                    "urls": {
                                                      "description": "Fixed http(s) URLs to read on every run, written out here — for pages that do not change per execution (a status page, a policy, a price list). Combine with \"from\" to read a fixed set plus whatever the run produced; the two lists concatenate, fixed URLs first.",
                                                      "type": "array",
                                                      "items": {
                                                        "type": "string"
                                                      }
                                                    },
                                                    "from": {
                                                      "description": "Dotted VALUE PATH (same resolution as forEach \"over\": workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — e.g. \"paraLer.soUrls\" or \"nodes.pick.result.urls\") to a URL list the run produced: an array of http(s) URL strings, a single URL string, or a JSON-encoded array string. Not a Handlebars template; a path wrapped in {{ }} is accepted and unwrapped.",
                                                      "type": "string",
                                                      "minLength": 1
                                                    }
                                                  }
                                                }
                                              },
                                              "required": [
                                                "instructions"
                                              ]
                                            }
                                          },
                                          "required": [
                                            "id",
                                            "type",
                                            "mode",
                                            "transition",
                                            "actionType",
                                            "config"
                                          ]
                                        },
                                        {
                                          "type": "object",
                                          "properties": {
                                            "id": {
                                              "description": "Unique identifier for this node.",
                                              "type": "string"
                                            },
                                            "type": {
                                              "type": "string",
                                              "const": "action"
                                            },
                                            "label": {
                                              "description": "Human-readable label for this action node.",
                                              "type": "string"
                                            },
                                            "mode": {
                                              "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                              "type": "string",
                                              "enum": [
                                                "sync",
                                                "async"
                                              ]
                                            },
                                            "outputVar": {
                                              "description": "Variable name to store the action output for use by downstream nodes.",
                                              "type": "string"
                                            },
                                            "transition": {
                                              "description": "Transitions to other nodes after this action completes.",
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "if": {
                                                    "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                    "$ref": "#/components/schemas/checkAgentImport_schema0"
                                                  },
                                                  "default": {
                                                    "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                    "type": "boolean"
                                                  },
                                                  "to": {
                                                    "type": "object",
                                                    "properties": {
                                                      "nodeId": {
                                                        "description": "The ID of the target node to transition to.",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "nodeId"
                                                    ]
                                                  },
                                                  "stop": {
                                                    "description": "If true, stop execution after this transition.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "to"
                                                ]
                                              }
                                            },
                                            "actionType": {
                                              "type": "string",
                                              "const": "EMAIL"
                                            },
                                            "config": {
                                              "type": "object",
                                              "properties": {
                                                "to": {
                                                  "type": "string"
                                                },
                                                "senderType": {
                                                  "type": "string",
                                                  "enum": [
                                                    "default",
                                                    "gmail"
                                                  ]
                                                },
                                                "gmailIntegrationId": {
                                                  "type": "string"
                                                },
                                                "subject": {
                                                  "type": "string"
                                                },
                                                "body": {
                                                  "type": "string"
                                                },
                                                "cc": {
                                                  "type": "string"
                                                },
                                                "bcc": {
                                                  "type": "string"
                                                },
                                                "attachments": {
                                                  "type": "array",
                                                  "items": {
                                                    "type": "object",
                                                    "properties": {
                                                      "documentId": {
                                                        "type": "number"
                                                      },
                                                      "url": {
                                                        "type": "string"
                                                      },
                                                      "filename": {
                                                        "type": "string"
                                                      }
                                                    }
                                                  }
                                                },
                                                "templateId": {
                                                  "type": "string"
                                                },
                                                "templateName": {
                                                  "type": "string"
                                                },
                                                "applicationId": {
                                                  "type": "number"
                                                }
                                              },
                                              "required": [
                                                "to",
                                                "subject",
                                                "body"
                                              ]
                                            }
                                          },
                                          "required": [
                                            "id",
                                            "type",
                                            "mode",
                                            "transition",
                                            "actionType",
                                            "config"
                                          ]
                                        },
                                        {
                                          "type": "object",
                                          "properties": {
                                            "id": {
                                              "description": "Unique identifier for this node.",
                                              "type": "string"
                                            },
                                            "type": {
                                              "type": "string",
                                              "const": "action"
                                            },
                                            "label": {
                                              "description": "Human-readable label for this action node.",
                                              "type": "string"
                                            },
                                            "mode": {
                                              "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                              "type": "string",
                                              "enum": [
                                                "sync",
                                                "async"
                                              ]
                                            },
                                            "outputVar": {
                                              "description": "Variable name to store the action output for use by downstream nodes.",
                                              "type": "string"
                                            },
                                            "transition": {
                                              "description": "Transitions to other nodes after this action completes.",
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "if": {
                                                    "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                    "$ref": "#/components/schemas/checkAgentImport_schema0"
                                                  },
                                                  "default": {
                                                    "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                    "type": "boolean"
                                                  },
                                                  "to": {
                                                    "type": "object",
                                                    "properties": {
                                                      "nodeId": {
                                                        "description": "The ID of the target node to transition to.",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "nodeId"
                                                    ]
                                                  },
                                                  "stop": {
                                                    "description": "If true, stop execution after this transition.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "to"
                                                ]
                                              }
                                            },
                                            "actionType": {
                                              "type": "string",
                                              "const": "WEBHOOK"
                                            },
                                            "config": {
                                              "type": "object",
                                              "properties": {
                                                "url": {
                                                  "type": "string"
                                                },
                                                "method": {
                                                  "type": "string",
                                                  "enum": [
                                                    "GET",
                                                    "POST",
                                                    "PUT",
                                                    "PATCH",
                                                    "DELETE"
                                                  ]
                                                },
                                                "headers": {
                                                  "type": "object",
                                                  "propertyNames": {
                                                    "type": "string"
                                                  },
                                                  "additionalProperties": {
                                                    "type": "string"
                                                  }
                                                },
                                                "queryParams": {
                                                  "type": "object",
                                                  "propertyNames": {
                                                    "type": "string"
                                                  },
                                                  "additionalProperties": {
                                                    "type": "string"
                                                  }
                                                },
                                                "body": {
                                                  "type": "string"
                                                },
                                                "timeout": {
                                                  "type": "number"
                                                },
                                                "responseMode": {
                                                  "description": "How to decode the response body. \"json\" (default): parse as JSON/text and expose via varsDelta. \"attachment\": read as binary bytes for multimodal input (e.g. PDFs, images).",
                                                  "type": "string",
                                                  "enum": [
                                                    "json",
                                                    "attachment"
                                                  ]
                                                },
                                                "asMessage": {
                                                  "description": "When true, append the response to the conversation as a new user message so downstream LLM nodes see it. In \"attachment\" mode the message carries a file content part; in \"json\" mode it carries the stringified body as text. Defaults to false — preserving the historical behavior where webhook responses only flow through varsDelta.",
                                                  "type": "boolean"
                                                },
                                                "suppressNoResponseFallback": {
                                                  "description": "Marks the webhook as a fire-and-forget trigger: the conversation is meant to end here, with the rest happening on the receiving system. When the call succeeds and the turn finishes without sending anything to the user, the channel skips its automatic \"sorry, something went wrong\" fallback message. A failed call (HTTP >= 400) still gets the fallback, since the user is then left waiting for nothing.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "url",
                                                "method"
                                              ]
                                            }
                                          },
                                          "required": [
                                            "id",
                                            "type",
                                            "mode",
                                            "transition",
                                            "actionType",
                                            "config"
                                          ]
                                        },
                                        {
                                          "type": "object",
                                          "properties": {
                                            "id": {
                                              "description": "Unique identifier for this node.",
                                              "type": "string"
                                            },
                                            "type": {
                                              "type": "string",
                                              "const": "action"
                                            },
                                            "label": {
                                              "description": "Human-readable label for this action node.",
                                              "type": "string"
                                            },
                                            "mode": {
                                              "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                              "type": "string",
                                              "enum": [
                                                "sync",
                                                "async"
                                              ]
                                            },
                                            "outputVar": {
                                              "description": "Variable name to store the action output for use by downstream nodes.",
                                              "type": "string"
                                            },
                                            "transition": {
                                              "description": "Transitions to other nodes after this action completes.",
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "if": {
                                                    "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                    "$ref": "#/components/schemas/checkAgentImport_schema0"
                                                  },
                                                  "default": {
                                                    "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                    "type": "boolean"
                                                  },
                                                  "to": {
                                                    "type": "object",
                                                    "properties": {
                                                      "nodeId": {
                                                        "description": "The ID of the target node to transition to.",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "nodeId"
                                                    ]
                                                  },
                                                  "stop": {
                                                    "description": "If true, stop execution after this transition.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "to"
                                                ]
                                              }
                                            },
                                            "actionType": {
                                              "type": "string",
                                              "const": "DOCUMENT_TEMPLATE"
                                            },
                                            "config": {
                                              "type": "object",
                                              "properties": {
                                                "templateId": {
                                                  "type": "string"
                                                },
                                                "templateName": {
                                                  "type": "string"
                                                },
                                                "sendEmail": {
                                                  "type": "boolean"
                                                },
                                                "sendWhatsApp": {
                                                  "type": "boolean"
                                                },
                                                "recipientEmail": {
                                                  "type": "string"
                                                }
                                              },
                                              "required": [
                                                "templateId"
                                              ]
                                            }
                                          },
                                          "required": [
                                            "id",
                                            "type",
                                            "mode",
                                            "transition",
                                            "actionType",
                                            "config"
                                          ]
                                        },
                                        {
                                          "type": "object",
                                          "properties": {
                                            "id": {
                                              "description": "Unique identifier for this node.",
                                              "type": "string"
                                            },
                                            "type": {
                                              "type": "string",
                                              "const": "action"
                                            },
                                            "label": {
                                              "description": "Human-readable label for this action node.",
                                              "type": "string"
                                            },
                                            "mode": {
                                              "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                              "type": "string",
                                              "enum": [
                                                "sync",
                                                "async"
                                              ]
                                            },
                                            "outputVar": {
                                              "description": "Variable name to store the action output for use by downstream nodes.",
                                              "type": "string"
                                            },
                                            "transition": {
                                              "description": "Transitions to other nodes after this action completes.",
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "if": {
                                                    "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                    "$ref": "#/components/schemas/checkAgentImport_schema0"
                                                  },
                                                  "default": {
                                                    "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                    "type": "boolean"
                                                  },
                                                  "to": {
                                                    "type": "object",
                                                    "properties": {
                                                      "nodeId": {
                                                        "description": "The ID of the target node to transition to.",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "nodeId"
                                                    ]
                                                  },
                                                  "stop": {
                                                    "description": "If true, stop execution after this transition.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "to"
                                                ]
                                              }
                                            },
                                            "actionType": {
                                              "type": "string",
                                              "const": "TOOL_CALL"
                                            },
                                            "config": {
                                              "type": "object",
                                              "properties": {
                                                "toolName": {
                                                  "description": "The name of the common tool to invoke.",
                                                  "type": "string"
                                                },
                                                "parameters": {
                                                  "description": "Per-parameter configuration. Keys are parameter names from the tool schema.",
                                                  "type": "object",
                                                  "propertyNames": {
                                                    "type": "string"
                                                  },
                                                  "additionalProperties": {
                                                    "type": "object",
                                                    "properties": {
                                                      "mode": {
                                                        "description": "Whether this parameter is hardcoded (static) or filled by the LLM at runtime (dynamic).",
                                                        "type": "string",
                                                        "enum": [
                                                          "static",
                                                          "dynamic"
                                                        ]
                                                      },
                                                      "staticValue": {
                                                        "description": "The fixed value for this parameter. Required when mode is \"static\"."
                                                      },
                                                      "instructions": {
                                                        "description": "Optional guidance for the LLM when filling this parameter (only used when mode is \"dynamic\").",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "mode"
                                                    ]
                                                  }
                                                },
                                                "instructions": {
                                                  "description": "General instructions for the LLM when resolving dynamic parameters.",
                                                  "type": "string"
                                                },
                                                "skipKnowledgeSearch": {
                                                  "description": "When a node has dynamic parameters, the model is normally forced to call similaritySearch first so parameter values are grounded in the knowledge base, costing one extra model round. Set true for tools that need no knowledge context (for example code execution) to call the configured tool directly. Ignored when every parameter is static, since no model runs at all.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "toolName"
                                              ]
                                            }
                                          },
                                          "required": [
                                            "id",
                                            "type",
                                            "mode",
                                            "transition",
                                            "actionType",
                                            "config"
                                          ]
                                        },
                                        {
                                          "type": "object",
                                          "properties": {
                                            "id": {
                                              "description": "Unique identifier for this node.",
                                              "type": "string"
                                            },
                                            "type": {
                                              "type": "string",
                                              "const": "action"
                                            },
                                            "label": {
                                              "description": "Human-readable label for this action node.",
                                              "type": "string"
                                            },
                                            "mode": {
                                              "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                              "type": "string",
                                              "enum": [
                                                "sync",
                                                "async"
                                              ]
                                            },
                                            "outputVar": {
                                              "description": "Variable name to store the action output for use by downstream nodes.",
                                              "type": "string"
                                            },
                                            "transition": {
                                              "description": "Transitions to other nodes after this action completes.",
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "if": {
                                                    "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                    "$ref": "#/components/schemas/checkAgentImport_schema0"
                                                  },
                                                  "default": {
                                                    "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                    "type": "boolean"
                                                  },
                                                  "to": {
                                                    "type": "object",
                                                    "properties": {
                                                      "nodeId": {
                                                        "description": "The ID of the target node to transition to.",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "nodeId"
                                                    ]
                                                  },
                                                  "stop": {
                                                    "description": "If true, stop execution after this transition.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "to"
                                                ]
                                              }
                                            },
                                            "actionType": {
                                              "type": "string",
                                              "const": "FOLLOW_UP"
                                            },
                                            "config": {
                                              "type": "object",
                                              "properties": {
                                                "delayMinutes": {
                                                  "description": "Minutes to wait before checking whether to run the inner action. Common presets: 5, 10, 15. Maximum 1440 (24h). Cloud Scheduler is cron-based so the actual fire time is rounded to the next minute boundary.",
                                                  "type": "integer",
                                                  "minimum": 1,
                                                  "maximum": 1440
                                                },
                                                "cancelOnUserMessage": {
                                                  "description": "When true (default), skip the inner action if any USER message arrived after the node was reached. Set to false only if the follow-up should fire even after the user has replied.",
                                                  "type": "boolean"
                                                },
                                                "cancelOnAssistantMessage": {
                                                  "description": "When true (default), skip the inner action if any ASSISTANT text message was sent after the node was reached. Tool-only assistant messages (no text content) do NOT count. Prevents double-pinging when another node already produced a response.",
                                                  "type": "boolean"
                                                },
                                                "cancelOnArchive": {
                                                  "description": "When true (default), skip the inner action if the thread was archived between scheduling and firing.",
                                                  "type": "boolean"
                                                },
                                                "action": {
                                                  "description": "The inner action to run when the delay elapses and cancel rules pass. INSTRUCTIONS produces an LLM-generated text message (good for \"Are you still there?\"-style nudges). TOOL_CALL fires a display tool (good for offering options or showing media).",
                                                  "oneOf": [
                                                    {
                                                      "type": "object",
                                                      "properties": {
                                                        "actionType": {
                                                          "type": "string",
                                                          "const": "INSTRUCTIONS"
                                                        },
                                                        "config": {
                                                          "type": "object",
                                                          "properties": {
                                                            "instructions": {
                                                              "description": "The instructions for the LLM to execute.",
                                                              "type": "string"
                                                            },
                                                            "modelTier": {
                                                              "description": "The model tier to use for this instruction. Defaults to regular.",
                                                              "type": "string",
                                                              "enum": [
                                                                "lite",
                                                                "regular",
                                                                "pro"
                                                              ]
                                                            },
                                                            "thinkingEffortPct": {
                                                              "description": "Thinking effort percentage (0-100) controlling how much reasoning the model applies.",
                                                              "type": "number",
                                                              "minimum": 0,
                                                              "maximum": 100
                                                            },
                                                            "maxOutputTokens": {
                                                              "description": "Maximum tokens the model may generate for this node. On thinking models the budget is SHARED between reasoning and output — reasoning routinely consumes most of it — so a node whose structured output is truncated is usually better served by lowering thinkingEffortPct than by raising this. Defaults to the model maximum when omitted.",
                                                              "type": "integer",
                                                              "minimum": 1,
                                                              "maximum": 9007199254740991
                                                            },
                                                            "maxRetries": {
                                                              "description": "How many times this node retries a failed model call. Defaults to 2 when the node has an outputSchema and 5 otherwise. Raise it for nodes whose long outputs are exposed to dropped provider streams; it does not help failures the model reproduces deterministically.",
                                                              "type": "integer",
                                                              "minimum": 1,
                                                              "maximum": 10
                                                            },
                                                            "toolChoiceMode": {
                                                              "description": "Tool selection mode for this instruction. Defaults to auto when omitted.",
                                                              "type": "string",
                                                              "enum": [
                                                                "auto",
                                                                "none",
                                                                "tool",
                                                                "tools"
                                                              ]
                                                            },
                                                            "toolChoiceToolName": {
                                                              "description": "When toolChoiceMode is \"tool\", the specific tool name to force.",
                                                              "type": "string"
                                                            },
                                                            "toolChoiceToolNames": {
                                                              "description": "When toolChoiceMode is \"tools\", the list of allowed tool names.",
                                                              "type": "array",
                                                              "items": {
                                                                "type": "string"
                                                              }
                                                            },
                                                            "suppressTextResponse": {
                                                              "description": "When true, text output from the LLM is suppressed and only tool-call results are emitted. Useful when the instruction should only invoke tools (e.g., displayMedia) without generating follow-up text.",
                                                              "type": "boolean"
                                                            },
                                                            "stopAfterFirstToolCall": {
                                                              "description": "When true and a single tool is forced with text suppressed, the instruction stops after the first successful tool call. Defaults to false, which allows the tool to be called across multiple steps.",
                                                              "type": "boolean"
                                                            },
                                                            "internal": {
                                                              "description": "When true, this node is an intermediate step: its text/structured output is NOT shown to the user (not streamed, not persisted as a visible message part) and is only captured into the node's outputVar for downstream nodes. Reasoning and tool-call activity chips remain visible. Use for internal hand-offs (e.g. tool-driven data synthesis a later node consumes); the user-facing reply should come from a later, non-internal node.",
                                                              "type": "boolean"
                                                            },
                                                            "outputSchema": {
                                                              "description": "JSON Schema for structured output. When provided, the LLM will output valid JSON matching this schema instead of free-form text.",
                                                              "type": "object",
                                                              "properties": {
                                                                "type": {
                                                                  "description": "JSON Schema type, must be \"object\" for structured output.",
                                                                  "type": "string",
                                                                  "const": "object"
                                                                },
                                                                "properties": {
                                                                  "description": "Schema properties defining the expected output structure.",
                                                                  "type": "object",
                                                                  "propertyNames": {
                                                                    "type": "string"
                                                                  },
                                                                  "additionalProperties": {}
                                                                },
                                                                "required": {
                                                                  "description": "Array of required property names.",
                                                                  "type": "array",
                                                                  "items": {
                                                                    "type": "string"
                                                                  }
                                                                },
                                                                "additionalProperties": {
                                                                  "description": "Whether to allow additional properties not defined in the schema.",
                                                                  "type": "boolean"
                                                                },
                                                                "description": {
                                                                  "description": "Description of the expected output to guide the LLM.",
                                                                  "type": "string"
                                                                }
                                                              },
                                                              "required": [
                                                                "type",
                                                                "properties"
                                                              ]
                                                            },
                                                            "grounding": {
                                                              "description": "Model-side grounding for this node. Only Google Search is available today.",
                                                              "type": "object",
                                                              "properties": {
                                                                "googleSearch": {
                                                                  "description": "Enable Google Search grounding: the model searches the public web (via Gemini's built-in google_search tool) while executing this instruction and answers from what it finds. Set `{}` to enable with defaults. The node result then carries `grounding` — the queries Google ran and the sources it cited, each with the resolved article URL, its domain and the passages of the reply it supports — readable downstream as `nodes.<nodeId>.grounding` in javascript nodes and templates; the text/JSON reply itself still flows through outputVar as usual. With an outputSchema the search runs first and the JSON is synthesized afterwards with the numbered source list, so declare a `sourceIds` or `url` field if you want citations inside the structured output. Incompatible with toolChoiceMode \"tool\" and with suppressTextResponse (a forced tool call and Google Search in one request returns an empty reply); with toolChoiceMode \"none\" the node still searches but calls no other tool. Each prompt costs Google one search query per query the model decides to run (usually 4–10), billed per query beyond the project's free tier.",
                                                                  "type": "object",
                                                                  "properties": {
                                                                    "excludeDomains": {
                                                                      "description": "Domains Google Search must not ground on, e.g. [\"youtube.com\", \"reddit.com\"]. A domain excludes its subdomains too.",
                                                                      "type": "array",
                                                                      "items": {
                                                                        "type": "string"
                                                                      }
                                                                    }
                                                                  }
                                                                }
                                                              }
                                                            },
                                                            "urlContext": {
                                                              "description": "Gemini URL context: hand the model a list of URLs to READ IN FULL server-side instead of fetching their text into a variable first. The URLs come from the fixed \"urls\" list, from the \"from\" value path, or from both (fixed first). They are appended to the end of the instruction and the provider fetches and reads the pages inside the same call. With an outputSchema the node runs as a SINGLE call (reading and synthesis must share it), so pair it with toolChoiceMode \"none\" unless the node truly needs function tools. Limits: 20 URLs per call (extra ones are dropped and reported as `truncated`), public pages only — paywalls, Google News redirect links and private hosts fail. The model may skip fetching when the URLs sit inside a very long prompt, so prefer a dedicated short reading node over bolting URLs onto a large synthesis prompt. The node output carries `urlContext.{requested,retrieved,unread,truncated,invalid,unresolved,supported,tokens}`. `unread` is the integrity signal — it lists every URL the model did not read, including the ones dropped by the 20-URL cap — so branch on `nodes.<id>.urlContext.unread` for a fallback reader (inside a forEach body it holds only the last item). `unresolved` says the \"from\" path resolved to nothing, `invalid` lists entries that were not http(s) URLs, and `supported` is false when the model could not carry the tool: in those cases nothing was read at all. Retrieved page content is billed as input tokens and added to the node usage as `urlContextTokens`. Gemini 3+ models only.",
                                                              "type": "object",
                                                              "properties": {
                                                                "urls": {
                                                                  "description": "Fixed http(s) URLs to read on every run, written out here — for pages that do not change per execution (a status page, a policy, a price list). Combine with \"from\" to read a fixed set plus whatever the run produced; the two lists concatenate, fixed URLs first.",
                                                                  "type": "array",
                                                                  "items": {
                                                                    "type": "string"
                                                                  }
                                                                },
                                                                "from": {
                                                                  "description": "Dotted VALUE PATH (same resolution as forEach \"over\": workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — e.g. \"paraLer.soUrls\" or \"nodes.pick.result.urls\") to a URL list the run produced: an array of http(s) URL strings, a single URL string, or a JSON-encoded array string. Not a Handlebars template; a path wrapped in {{ }} is accepted and unwrapped.",
                                                                  "type": "string",
                                                                  "minLength": 1
                                                                }
                                                              }
                                                            }
                                                          },
                                                          "required": [
                                                            "instructions"
                                                          ]
                                                        }
                                                      },
                                                      "required": [
                                                        "actionType",
                                                        "config"
                                                      ]
                                                    },
                                                    {
                                                      "type": "object",
                                                      "properties": {
                                                        "actionType": {
                                                          "type": "string",
                                                          "const": "TOOL_CALL"
                                                        },
                                                        "config": {
                                                          "type": "object",
                                                          "properties": {
                                                            "toolName": {
                                                              "description": "The name of the common tool to invoke.",
                                                              "type": "string"
                                                            },
                                                            "parameters": {
                                                              "description": "Per-parameter configuration. Keys are parameter names from the tool schema.",
                                                              "type": "object",
                                                              "propertyNames": {
                                                                "type": "string"
                                                              },
                                                              "additionalProperties": {
                                                                "type": "object",
                                                                "properties": {
                                                                  "mode": {
                                                                    "description": "Whether this parameter is hardcoded (static) or filled by the LLM at runtime (dynamic).",
                                                                    "type": "string",
                                                                    "enum": [
                                                                      "static",
                                                                      "dynamic"
                                                                    ]
                                                                  },
                                                                  "staticValue": {
                                                                    "description": "The fixed value for this parameter. Required when mode is \"static\"."
                                                                  },
                                                                  "instructions": {
                                                                    "description": "Optional guidance for the LLM when filling this parameter (only used when mode is \"dynamic\").",
                                                                    "type": "string"
                                                                  }
                                                                },
                                                                "required": [
                                                                  "mode"
                                                                ]
                                                              }
                                                            },
                                                            "instructions": {
                                                              "description": "General instructions for the LLM when resolving dynamic parameters.",
                                                              "type": "string"
                                                            },
                                                            "skipKnowledgeSearch": {
                                                              "description": "When a node has dynamic parameters, the model is normally forced to call similaritySearch first so parameter values are grounded in the knowledge base, costing one extra model round. Set true for tools that need no knowledge context (for example code execution) to call the configured tool directly. Ignored when every parameter is static, since no model runs at all.",
                                                              "type": "boolean"
                                                            }
                                                          },
                                                          "required": [
                                                            "toolName"
                                                          ]
                                                        }
                                                      },
                                                      "required": [
                                                        "actionType",
                                                        "config"
                                                      ]
                                                    }
                                                  ]
                                                }
                                              },
                                              "required": [
                                                "delayMinutes",
                                                "action"
                                              ]
                                            }
                                          },
                                          "required": [
                                            "id",
                                            "type",
                                            "mode",
                                            "transition",
                                            "actionType",
                                            "config"
                                          ]
                                        }
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "subAgent"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this sub-agent node.",
                                          "type": "string"
                                        },
                                        "agentId": {
                                          "description": "The ID of the sub-agent to invoke.",
                                          "type": "string"
                                        },
                                        "instructions": {
                                          "description": "Optional instructions message prepended to the sub-agent conversation. Supports Handlebars interpolation against the parent execution scope: `{{var}}` reads workflow vars, `{{context.x}}` reads contextVars, `{{env.X}}` reads environment, `{{input.text}}` reads the original user input, and `{{nodes.<id>.<path>}}` reads prior node outputs.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Optional transitions to continue the flow after the sub-agent returns.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/checkAgentImport_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "agentId"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "end"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this end node.",
                                          "type": "string"
                                        },
                                        "config": {
                                          "description": "Optional configuration for the end node behavior.",
                                          "type": "object",
                                          "properties": {
                                            "resetConversationHistory": {
                                              "description": "If true, the next user message starts a new conversation with no prior history.",
                                              "type": "boolean"
                                            }
                                          }
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "state"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this state node.",
                                          "type": "string"
                                        },
                                        "outputVar": {
                                          "description": "Agent-scope get only: variable name that receives the value stored under `config.key` (null when the key has never been written). Downstream templates read it as `{{<outputVar>}}`; transition conditions as `{source:\"vars\", path:\"<outputVar>...\"}`.",
                                          "type": "string"
                                        },
                                        "config": {
                                          "type": "object",
                                          "properties": {
                                            "scope": {
                                              "description": "How long the data lives and who sees it. execution: this run only. session: this conversation (thread) — a NEW conversation starts empty. agent: durable memory shared by every execution of this agent, across conversations — use it to remember things between independent runs. Survives clearCache.",
                                              "type": "string",
                                              "enum": [
                                                "execution",
                                                "session",
                                                "agent"
                                              ]
                                            },
                                            "operation": {
                                              "description": "Agent scope only (default set). set: durably store the `state` entries. get: read the entry under `key` into `outputVar`. Execution/session scopes are always set — their values are injected into templates automatically, so no get is needed.",
                                              "type": "string",
                                              "enum": [
                                                "set",
                                                "get"
                                              ]
                                            },
                                            "key": {
                                              "description": "Agent-scope get: the memory key to read. Supports Handlebars (e.g. \"evidence-{{context.cnpj}}\") so one node can address per-entity entries. Rendered keys are limited to 512 characters.",
                                              "type": "string"
                                            },
                                            "state": {
                                              "description": "Key-value pairs to set (required for set operations). String values support Handlebars. In agent scope the KEYS are templates too (e.g. \"evidence-{{context.cnpj}}\"), each entry is stored as its own durable row, and serialized values are size-capped.",
                                              "type": "object",
                                              "propertyNames": {
                                                "type": "string"
                                              },
                                              "additionalProperties": {}
                                            }
                                          },
                                          "required": [
                                            "scope"
                                          ]
                                        },
                                        "transition": {
                                          "description": "Optional transitions to continue the flow after setting state.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/checkAgentImport_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "config"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "hub"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this hub node.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Transitions to route connections to other nodes.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/checkAgentImport_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "jump"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this jump node.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Target node to jump to unconditionally.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/checkAgentImport_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "clearCache"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this clear cache node.",
                                          "type": "string"
                                        },
                                        "config": {
                                          "description": "Optional configuration controlling what is cleared.",
                                          "type": "object",
                                          "properties": {
                                            "clearScope": {
                                              "description": "What to clear. executionCache (default): clears only the decision result cache. all: clears the entire session state including user-defined session variables.",
                                              "type": "string",
                                              "enum": [
                                                "executionCache",
                                                "all"
                                              ]
                                            }
                                          }
                                        },
                                        "transition": {
                                          "description": "Optional transitions to continue the flow after clearing cache.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/checkAgentImport_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "javascript"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this JavaScript node.",
                                          "type": "string"
                                        },
                                        "outputVar": {
                                          "description": "Variable name to store the returned value for downstream nodes. Downstream templates read it as `{{<outputVar>}}`; transition conditions as `{source:\"vars\", path:\"<outputVar>...\"}`.",
                                          "type": "string"
                                        },
                                        "config": {
                                          "type": "object",
                                          "properties": {
                                            "code": {
                                              "description": "JavaScript source executed in a sandboxed QuickJS interpreter. Written as a function body: it receives ({ vars, evaluation, context, env, input, nodes }) and must `return` a JSON-serializable value. Synchronous only — no network, filesystem, require/import, or timers.",
                                              "type": "string"
                                            },
                                            "timeoutMs": {
                                              "description": "CPU deadline in milliseconds. Default 1000, max 10000.",
                                              "type": "integer",
                                              "minimum": 1,
                                              "maximum": 10000
                                            }
                                          },
                                          "required": [
                                            "code"
                                          ]
                                        },
                                        "transition": {
                                          "description": "Optional transitions to continue the flow after the code runs.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/checkAgentImport_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "config"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "forEach"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this forEach node.",
                                          "type": "string"
                                        },
                                        "over": {
                                          "description": "Dotted path to the array to iterate, resolved against the execution scope: top-level workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — for example \"research.socioAlvos\" or \"nodes.build_plan.result.targets\". This is a VALUE PATH, not a Handlebars template: Handlebars renders to a string, so an array passed through it would arrive as \"[object Object]\". A path wrapped in {{ }} is accepted and unwrapped. If the path does not resolve to an array the node fails loudly instead of iterating a string.",
                                          "type": "string"
                                        },
                                        "as": {
                                          "description": "Variable name bound to the current element inside the body node: \"socio\" makes {{socio.nome}} available to the body's templates. Must not be \"iteration\", which is reserved for the {index, total} binding also exposed to the body.",
                                          "type": "string"
                                        },
                                        "each": {
                                          "description": "The body node, referenced by ID. Must be an action, javascript or subAgent node declared in workflow.nodes with no other incoming transitions, and must not be an entry point. Its own \"transition\" array is ignored — the forEach node owns what happens after every item finishes. decision nodes are rejected because the execution cache is keyed by node ID, so parallel instances would contend for one cache entry.",
                                          "type": "object",
                                          "properties": {
                                            "nodeId": {
                                              "description": "The ID of the node to run once per item.",
                                              "type": "string"
                                            }
                                          },
                                          "required": [
                                            "nodeId"
                                          ]
                                        },
                                        "collectInto": {
                                          "description": "Variable name receiving the per-item results array. Each entry is {index, item, ok, value?, grounding?, error?, errorName?}, where \"value\" is whatever the body node's own outputVar would have held (undefined when the body declares none) and \"grounding\" is that item's Google Search queries and sources when the body is a grounded INSTRUCTIONS node — the same shape a standalone node exposes as nodes.<id>.grounding. Entries stay aligned with the source array by index, including failed items, so a downstream node can tell \"this item returned nothing\" apart from \"this item was never tried\". Omit only if nothing downstream needs the results.",
                                          "type": "string"
                                        },
                                        "maxConcurrency": {
                                          "description": "How many items run at once. Defaults to 5. Raise carefully: per-item parallelism hits provider rate limits well before it hits platform limits.",
                                          "type": "integer",
                                          "minimum": 1,
                                          "maximum": 20
                                        },
                                        "transition": {
                                          "description": "Transitions to continue the flow after every item has finished.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/checkAgentImport_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "over",
                                        "as",
                                        "each"
                                      ]
                                    }
                                  ]
                                }
                              }
                            },
                            "required": [
                              "toolName",
                              "toolDescription",
                              "entryPoints",
                              "nodes"
                            ]
                          },
                          "tools": {
                            "deprecated": true,
                            "description": "Deprecated and ignored. Tool availability is configured by the application, not the agent spec.",
                            "type": "array",
                            "items": {}
                          },
                          "metadata": {
                            "description": "Arbitrary metadata for custom extensions. Not used by the execution engine.",
                            "type": "object",
                            "propertyNames": {
                              "type": "string"
                            },
                            "additionalProperties": {}
                          }
                        },
                        "required": [
                          "version",
                          "name",
                          "prompt",
                          "workflow"
                        ]
                      },
                      "evals": {
                        "default": [],
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "name": {
                              "type": "string",
                              "minLength": 1
                            },
                            "description": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "scheduler": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "evalSpec": {},
                            "enabled": {
                              "type": "boolean"
                            },
                            "selfImproveEnabled": {
                              "type": "boolean"
                            },
                            "selfImproveTargetScore": {
                              "anyOf": [
                                {
                                  "type": "number"
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "selfImproveMaxIterations": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            "folderPath": {
                              "description": "Materialized '/'-separated folder path of the eval (e.g. 'Regressão/Checkout'), or null for root.",
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "tags": {
                              "description": "Free-form labels of the eval.",
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "metadata": {
                              "description": "Free-form data of the eval, including the `sources` conversations it was built from.",
                              "anyOf": [
                                {
                                  "description": "Free-form data recorded on the eval. Provenance belongs under `sources`, a list whose entries have documented keys so every writer points at the originating conversations the same way. An eval drawn from a single conversation carries a one-element list.",
                                  "type": "object",
                                  "properties": {
                                    "sources": {
                                      "description": "The conversations the eval was built from, most relevant first.",
                                      "maxItems": 25,
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "threadId": {
                                            "description": "Id of the thread the eval was built from.",
                                            "examples": [
                                              "cmc3k5r2b0004l608w1t8fmz9"
                                            ],
                                            "type": "string",
                                            "minLength": 1,
                                            "maxLength": 255
                                          },
                                          "executionId": {
                                            "description": "Id of the agent execution the eval was built from.",
                                            "examples": [
                                              "exec_01j9z3k2b4c5"
                                            ],
                                            "type": "string",
                                            "minLength": 1,
                                            "maxLength": 255
                                          },
                                          "messageId": {
                                            "description": "Id of the specific message the eval was built from.",
                                            "examples": [
                                              "cmc3k9p7f0007"
                                            ],
                                            "type": "string",
                                            "minLength": 1,
                                            "maxLength": 255
                                          },
                                          "url": {
                                            "description": "Link to the source conversation. Must be an absolute http(s) URL.",
                                            "examples": [
                                              "https://platform.docana.com/application/42/agents/a1/logs?search=thread-1"
                                            ],
                                            "type": "string",
                                            "minLength": 1,
                                            "maxLength": 2048
                                          },
                                          "label": {
                                            "description": "Human friendly name of the source conversation.",
                                            "examples": [
                                              "WhatsApp 5511 — 12/08"
                                            ],
                                            "type": "string",
                                            "minLength": 1,
                                            "maxLength": 255
                                          },
                                          "capturedAt": {
                                            "description": "ISO 8601 timestamp of when the eval was captured.",
                                            "examples": [
                                              "2026-08-17T12:00:00.000Z"
                                            ],
                                            "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))$"
                                          }
                                        },
                                        "additionalProperties": {}
                                      }
                                    }
                                  },
                                  "additionalProperties": {}
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            }
                          },
                          "required": [
                            "name",
                            "evalSpec"
                          ]
                        }
                      },
                      "routines": {
                        "default": [],
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "name": {
                              "type": "string",
                              "minLength": 1
                            },
                            "prompt": {
                              "type": "string"
                            },
                            "enabled": {
                              "default": true,
                              "type": "boolean"
                            },
                            "metadata": {
                              "anyOf": [
                                {
                                  "type": "object",
                                  "propertyNames": {
                                    "type": "string"
                                  },
                                  "additionalProperties": {}
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "triggers": {
                              "default": [],
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "enum": [
                                      "SCHEDULED",
                                      "API",
                                      "DOCUMENT_EVENT"
                                    ]
                                  },
                                  "enabled": {
                                    "default": true,
                                    "type": "boolean"
                                  },
                                  "cronExpression": {
                                    "anyOf": [
                                      {
                                        "type": "string"
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ]
                                  },
                                  "collectionIds": {
                                    "default": [],
                                    "type": "array",
                                    "items": {
                                      "type": "integer",
                                      "minimum": -9007199254740991,
                                      "maximum": 9007199254740991
                                    }
                                  },
                                  "eventName": {
                                    "anyOf": [
                                      {
                                        "type": "string"
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ]
                                  },
                                  "metadata": {
                                    "type": "object",
                                    "propertyNames": {
                                      "type": "string"
                                    },
                                    "additionalProperties": {}
                                  }
                                },
                                "required": [
                                  "type"
                                ]
                              }
                            }
                          },
                          "required": [
                            "name",
                            "prompt"
                          ]
                        }
                      },
                      "insights": {
                        "anyOf": [
                          {
                            "type": "object",
                            "properties": {
                              "enabled": {
                                "description": "Master kill switch for this agent's insights. When false, no extraction runs anywhere (the post-execution hook is suppressed and the archive API rejects summarize=true) and no prior insights are injected into new conversations.",
                                "type": "boolean"
                              },
                              "shareWithPastConversations": {
                                "description": "When true (and `enabled` is true), inject summaries from this user's past archived conversations in the same application into LLM calls that consume conversation history (instruction nodes; decision criteria with EvaluationParams.CONTEXT). Defaults to false.",
                                "type": "boolean"
                              },
                              "summaryMode": {
                                "description": "When to extract insights for this agent. \"afterExecution\" (default) runs archive + extraction after every successful agent turn (with or without an End node), so channels like WhatsApp keep producing insights. \"onArchive\" skips the automatic hook; insights are only extracted when the archive API is called with summarize=true.",
                                "type": "string",
                                "enum": [
                                  "afterExecution",
                                  "onArchive"
                                ]
                              },
                              "summaryConfig": {
                                "description": "Config used when this agent extracts a new summary (End-node generateInsights or archive API with summarize=true).",
                                "type": "object",
                                "properties": {
                                  "summaryLength": {
                                    "description": "Target length of the generated summary.",
                                    "type": "string",
                                    "enum": [
                                      "short",
                                      "medium",
                                      "detailed"
                                    ]
                                  },
                                  "customPrompt": {
                                    "description": "Optional extra guidance appended to the summarizer system prompt.",
                                    "type": "string"
                                  },
                                  "historyMessageLimit": {
                                    "description": "Cap on the number of recent messages included when generating the summary. Omitted = no cap.",
                                    "type": "integer",
                                    "exclusiveMinimum": 0,
                                    "maximum": 9007199254740991
                                  },
                                  "maxSummaryChars": {
                                    "description": "Optional cap on the persisted summary length (characters).",
                                    "type": "integer",
                                    "exclusiveMinimum": 0,
                                    "maximum": 9007199254740991
                                  }
                                }
                              },
                              "frequency": {
                                "description": "How often insights are extracted. \"onEnd\" (default) extracts once when the conversation is archived. \"everyTurn\" extracts after every message — the legacy behaviour, which costs roughly O(N^2) tokens over an N-turn conversation. When absent, the legacy `summaryMode` is used: \"afterExecution\" maps to \"everyTurn\", anything else maps to \"onEnd\". Any other stored value (e.g. a removed legacy mode) resolves to \"onEnd\", the cheap option.",
                                "type": "string",
                                "enum": [
                                  "onEnd",
                                  "everyTurn"
                                ]
                              },
                              "samplingRate": {
                                "description": "Share of conversations that produce insights automatically, 0..1. Defaults to 1 (all). The decision is a deterministic hash of (agentId, threadId), so a conversation is either sampled for its whole life or not at all. Explicit archive calls and on-demand generation always run regardless of this rate.",
                                "type": "number",
                                "minimum": 0,
                                "maximum": 1
                              },
                              "dataPoints": {
                                "description": "Structured data points to extract from the conversation when generating insights.",
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Stable identifier for the data point; reused across saves so snapshot history and aggregations stay correlated over time.",
                                      "type": "string"
                                    },
                                    "name": {
                                      "description": "Human-readable name of the data point (displayed in the UI).",
                                      "type": "string"
                                    },
                                    "description": {
                                      "description": "Instruction describing what this data point should capture from the conversation.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "description": "The expected type of the extracted value.",
                                      "type": "string",
                                      "enum": [
                                        "string",
                                        "number",
                                        "boolean"
                                      ]
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "name",
                                    "description",
                                    "type"
                                  ]
                                }
                              }
                            },
                            "required": [
                              "enabled"
                            ]
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "evalMockBaseline": {
                        "anyOf": [
                          {
                            "type": "object",
                            "propertyNames": {
                              "type": "string"
                            },
                            "additionalProperties": {
                              "anyOf": [
                                {
                                  "type": "object",
                                  "properties": {
                                    "type": {
                                      "examples": [
                                        "webhook"
                                      ],
                                      "type": "string",
                                      "const": "webhook"
                                    },
                                    "mode": {
                                      "default": "staticResponse",
                                      "type": "string",
                                      "const": "staticResponse"
                                    },
                                    "response": {
                                      "anyOf": [
                                        {
                                          "type": "object",
                                          "properties": {
                                            "status": {
                                              "examples": [
                                                200
                                              ],
                                              "type": "integer",
                                              "minimum": 100,
                                              "maximum": 599
                                            },
                                            "headers": {
                                              "examples": [
                                                {
                                                  "content-type": "application/json"
                                                }
                                              ],
                                              "type": "object",
                                              "propertyNames": {
                                                "type": "string"
                                              },
                                              "additionalProperties": {
                                                "type": "string"
                                              }
                                            },
                                            "body": {
                                              "examples": [
                                                {
                                                  "orderStatus": "shipped"
                                                }
                                              ],
                                              "$ref": "#/components/schemas/checkAgentImport_schema1"
                                            },
                                            "noResponse": {
                                              "not": {}
                                            }
                                          },
                                          "required": [
                                            "status"
                                          ]
                                        },
                                        {
                                          "type": "object",
                                          "properties": {
                                            "noResponse": {
                                              "examples": [
                                                true
                                              ],
                                              "type": "boolean",
                                              "const": true
                                            },
                                            "error": {
                                              "examples": [
                                                "connect ECONNREFUSED 10.0.0.4:443"
                                              ],
                                              "type": "string"
                                            },
                                            "status": {
                                              "not": {}
                                            }
                                          },
                                          "required": [
                                            "noResponse"
                                          ]
                                        }
                                      ]
                                    }
                                  },
                                  "required": [
                                    "type",
                                    "response"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "type": {
                                      "examples": [
                                        "webhook"
                                      ],
                                      "type": "string",
                                      "const": "webhook"
                                    },
                                    "mode": {
                                      "type": "string",
                                      "const": "sequence"
                                    },
                                    "responses": {
                                      "examples": [
                                        [
                                          {
                                            "status": 400,
                                            "body": {
                                              "error": "CEP inválido"
                                            }
                                          },
                                          {
                                            "status": 201,
                                            "body": {
                                              "data": {
                                                "status": "AUTORIZADA"
                                              }
                                            }
                                          }
                                        ]
                                      ],
                                      "minItems": 1,
                                      "type": "array",
                                      "items": {
                                        "anyOf": [
                                          {
                                            "type": "object",
                                            "properties": {
                                              "status": {
                                                "examples": [
                                                  200
                                                ],
                                                "type": "integer",
                                                "minimum": 100,
                                                "maximum": 599
                                              },
                                              "headers": {
                                                "examples": [
                                                  {
                                                    "content-type": "application/json"
                                                  }
                                                ],
                                                "type": "object",
                                                "propertyNames": {
                                                  "type": "string"
                                                },
                                                "additionalProperties": {
                                                  "type": "string"
                                                }
                                              },
                                              "body": {
                                                "examples": [
                                                  {
                                                    "orderStatus": "shipped"
                                                  }
                                                ],
                                                "$ref": "#/components/schemas/checkAgentImport_schema1"
                                              },
                                              "noResponse": {
                                                "not": {}
                                              }
                                            },
                                            "required": [
                                              "status"
                                            ]
                                          },
                                          {
                                            "type": "object",
                                            "properties": {
                                              "noResponse": {
                                                "examples": [
                                                  true
                                                ],
                                                "type": "boolean",
                                                "const": true
                                              },
                                              "error": {
                                                "examples": [
                                                  "connect ECONNREFUSED 10.0.0.4:443"
                                                ],
                                                "type": "string"
                                              },
                                              "status": {
                                                "not": {}
                                              }
                                            },
                                            "required": [
                                              "noResponse"
                                            ]
                                          }
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "type",
                                    "mode",
                                    "responses"
                                  ]
                                }
                              ]
                            }
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "required": [
                      "spec"
                    ]
                  },
                  "subAgents": {
                    "default": [],
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "sourceId": {
                          "description": "The id this entry had in the bundle, when `id` points at an agent that already exists in the target application. Stored as the imported agent's origin so a later import of the same bundle still recognizes it.",
                          "type": "string"
                        },
                        "name": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "description": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "spec": {
                          "type": "object",
                          "properties": {
                            "version": {
                              "description": "Schema version. Must be \"2.0\".",
                              "type": "string",
                              "const": "2.0"
                            },
                            "id": {
                              "description": "Unique identifier for this agent. Auto-generated if not provided.",
                              "type": "string"
                            },
                            "name": {
                              "description": "Human-readable name of the agent.",
                              "type": "string"
                            },
                            "prompt": {
                              "description": "System instructions for the agent. Can be a single string or an array of strings joined at runtime.",
                              "anyOf": [
                                {
                                  "type": "string",
                                  "minLength": 1
                                },
                                {
                                  "minItems": 1,
                                  "type": "array",
                                  "items": {
                                    "type": "string",
                                    "minLength": 1
                                  }
                                }
                              ]
                            },
                            "llm": {
                              "description": "LLM configuration for the router persona. Optional; uses platform defaults when omitted.",
                              "type": "object",
                              "properties": {
                                "provider": {
                                  "description": "The LLM provider identifier (e.g., \"google\", \"openai\").",
                                  "type": "string"
                                },
                                "model": {
                                  "description": "The model name to use (e.g., \"gemini-2.0-flash\").",
                                  "type": "string"
                                },
                                "temperature": {
                                  "description": "Sampling temperature (0-2). IGNORED on Gemini 3.x models, which Google deprecated this parameter for on 2026-07-21 — it is accepted and silently discarded, so it no longer makes output more deterministic. Still accepted for older models and for backwards compatibility with existing specs.",
                                  "type": "number"
                                },
                                "maxOutputTokens": {
                                  "description": "Maximum number of tokens the model can generate.",
                                  "type": "number"
                                },
                                "toolChoice": {
                                  "description": "Controls how the model uses tools: auto (model decides), required (must use a tool), none (no tools).",
                                  "type": "string",
                                  "enum": [
                                    "auto",
                                    "required",
                                    "none"
                                  ]
                                },
                                "jsonMode": {
                                  "description": "If true, the model outputs valid JSON.",
                                  "type": "boolean"
                                }
                              },
                              "required": [
                                "provider",
                                "model"
                              ]
                            },
                            "inlineEvaluationCriteria": {
                              "description": "Map of criteria ID to its full definition. Decision nodes reference these by key. These are criteria that have not been persisted to the database yet. During sandbox execution, they are loaded into memory. During publish, they are persisted to the database and this field is cleared.",
                              "type": "object",
                              "propertyNames": {
                                "type": "string"
                              },
                              "additionalProperties": {
                                "type": "object",
                                "properties": {
                                  "name": {
                                    "description": "Human-readable name of this evaluation criteria. MUST be a non-empty short noun phrase (e.g. \"Real-Estate Availability Intent\"). Empty strings are forbidden.",
                                    "type": "string"
                                  },
                                  "type": {
                                    "description": "The evaluation criteria type (e.g., CUSTOM, QUALITY_HELPFULNESS).",
                                    "type": "string",
                                    "enum": [
                                      "QUALITY_ENGAGINGNESS",
                                      "QUALITY_COHERENCE",
                                      "QUALITY_CONSISTENCY",
                                      "QUALITY_FLUENCY",
                                      "QUALITY_RELEVANCE",
                                      "SECURITY_FINANCIAL_DETECTION",
                                      "SECURITY_PII_DETECTION",
                                      "SECURITY_ANOMALOUS_CONVERSATION",
                                      "PERSONALITY_EXTRAVERSION",
                                      "PERSONALITY_OPEN_TO_EXPERIENCE",
                                      "PERSONALITY_CONSCIENTIOUSNESS",
                                      "PERSONALITY_AGREEABLENESS",
                                      "PERSONALITY_NEUROTICISM",
                                      "PERSONALITY_OTHER",
                                      "DOCUMENT_INSIGHTS",
                                      "CUSTOM"
                                    ]
                                  },
                                  "evaluationCriteria": {
                                    "description": "REQUIRED non-empty instruction the evaluator follows to assess the input. One or two sentences in plain language: what to assess, and (if structuredDataParams is set) how to populate each declared field. Example: \"Decide whether the user is asking about real-estate availability. Set isAvailability to true only when the user is clearly asking whether a property is available; otherwise false.\" Empty strings, null, or omission make the reasoning useless and are forbidden.",
                                    "type": "string"
                                  },
                                  "evaluationSteps": {
                                    "description": "Ordered evaluation steps for the criteria.",
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "evaluationParams": {
                                    "description": "Parameters used during evaluation (e.g., INPUT, CONTEXT).",
                                    "type": "array",
                                    "items": {
                                      "type": "string",
                                      "enum": [
                                        "INPUT",
                                        "ACTUAL_OUTPUT",
                                        "EXPECTED_OUTPUT",
                                        "CONTEXT",
                                        "RETRIEVAL_CONTEXT",
                                        "EXECUTION_CONTEXT"
                                      ]
                                    }
                                  },
                                  "structuredDataParams": {
                                    "description": "Map of field name to a natural-language description of what to extract. The description should encode both the type and the legal values, e.g. \"true if the user is asking about real-estate availability, false otherwise\" (boolean), \"one of: AVAILABILITY, PRICING, CONTACT, OTHER\" (enum), or \"numeric score 1-5 reflecting urgency\" (number). Each declared field becomes a routing key accessible from transition conditions as \"evaluation.structuredData.<field>\" (and is also flattened into top-level vars for action templates). Prefer this for routing on what the user meant or asked; use scores.mean for confidence/quality routing.",
                                    "anyOf": [
                                      {
                                        "type": "object",
                                        "propertyNames": {
                                          "type": "string"
                                        },
                                        "additionalProperties": {}
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ]
                                  },
                                  "metadata": {
                                    "description": "Additional metadata for the criteria.",
                                    "anyOf": [
                                      {
                                        "type": "object",
                                        "propertyNames": {
                                          "type": "string"
                                        },
                                        "additionalProperties": {}
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ]
                                  },
                                  "enabled": {
                                    "description": "Whether this criteria is enabled. Defaults to true.",
                                    "type": "boolean"
                                  }
                                },
                                "required": [
                                  "name",
                                  "type",
                                  "evaluationCriteria"
                                ]
                              }
                            },
                            "workflow": {
                              "description": "The workflow definition including entry points and execution nodes.",
                              "type": "object",
                              "properties": {
                                "toolName": {
                                  "description": "The tool name used to invoke this agent in the workflow.",
                                  "type": "string"
                                },
                                "toolDescription": {
                                  "description": "A description of what this agent does, shown to the LLM router.",
                                  "type": "string"
                                },
                                "executionTimeoutSeconds": {
                                  "description": "Wall-clock ceiling for ONE execution of this workflow, in seconds (30-1800). When the deadline passes the run is aborted — in-flight model calls are cancelled, sub-agents included — and the execution finishes with status TIMED_OUT, with the reason recorded on the nodes that were cut. Optional: an agent that declares nothing keeps the platform behavior (no explicit ceiling). Declare it when the agent legitimately runs for minutes (deep research, long tool chains) so a slow run is never mistaken for a hung one, or when it must never occupy a worker past a known bound. The budget is per attempt: a run resumed after a crash starts a fresh timer.",
                                  "type": "integer",
                                  "minimum": 30,
                                  "maximum": 1800
                                },
                                "entryPoints": {
                                  "description": "Entry points into the workflow. MUST contain at least one node ID; an empty array makes the workflow non-executable. When you restructure or rename the first node, update this list in the same operation so it points at the new entry node.",
                                  "minItems": 1,
                                  "type": "array",
                                  "items": {
                                    "anyOf": [
                                      {
                                        "description": "Node ID to use as an unconditional entry point.",
                                        "type": "string"
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "nodeId": {
                                            "description": "The ID of the entry point node.",
                                            "type": "string"
                                          },
                                          "if": {
                                            "description": "Optional condition that must be met for this entry point to activate.",
                                            "$ref": "#/components/schemas/checkAgentImport_schema0"
                                          }
                                        },
                                        "required": [
                                          "nodeId"
                                        ]
                                      }
                                    ]
                                  }
                                },
                                "nodes": {
                                  "description": "The workflow nodes: decision, action, subAgent, end, state, hub, jump, clearCache, javascript, or forEach.",
                                  "type": "array",
                                  "items": {
                                    "anyOf": [
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "decision"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this decision node.",
                                            "type": "string"
                                          },
                                          "evaluationCriteria": {
                                            "description": "Evaluation criteria IDs (string references) or inline criteria objects.",
                                            "type": "array",
                                            "items": {
                                              "anyOf": [
                                                {
                                                  "type": "string"
                                                },
                                                {
                                                  "type": "object",
                                                  "properties": {
                                                    "id": {
                                                      "type": "string"
                                                    },
                                                    "name": {
                                                      "description": "Required non-empty short human-readable name for this criterion (e.g. \"Real-Estate Availability Intent\"). Never an empty string.",
                                                      "type": "string"
                                                    },
                                                    "type": {
                                                      "type": "string",
                                                      "enum": [
                                                        "QUALITY_ENGAGINGNESS",
                                                        "QUALITY_COHERENCE",
                                                        "QUALITY_CONSISTENCY",
                                                        "QUALITY_FLUENCY",
                                                        "QUALITY_RELEVANCE",
                                                        "SECURITY_FINANCIAL_DETECTION",
                                                        "SECURITY_PII_DETECTION",
                                                        "SECURITY_ANOMALOUS_CONVERSATION",
                                                        "PERSONALITY_EXTRAVERSION",
                                                        "PERSONALITY_OPEN_TO_EXPERIENCE",
                                                        "PERSONALITY_CONSCIENTIOUSNESS",
                                                        "PERSONALITY_AGREEABLENESS",
                                                        "PERSONALITY_NEUROTICISM",
                                                        "PERSONALITY_OTHER",
                                                        "DOCUMENT_INSIGHTS",
                                                        "CUSTOM"
                                                      ]
                                                    },
                                                    "evaluationCriteria": {
                                                      "description": "REQUIRED non-empty instruction telling the evaluator what to assess. One or two sentences in plain language: what to evaluate, and — when structuredDataParams is set — how to populate each declared field. Empty strings, null, or omission are forbidden; an empty description leaves the reasoning useless. Example: \"Decide whether the user is asking about real-estate availability. Set isAvailability to true only when the user is clearly asking whether a property is available; otherwise false.\"",
                                                      "type": "string"
                                                    },
                                                    "evaluationSteps": {
                                                      "type": "array",
                                                      "items": {
                                                        "type": "string"
                                                      }
                                                    },
                                                    "structuredDataParams": {
                                                      "anyOf": [
                                                        {
                                                          "type": "object",
                                                          "propertyNames": {
                                                            "type": "string"
                                                          },
                                                          "additionalProperties": {}
                                                        },
                                                        {
                                                          "type": "null"
                                                        }
                                                      ]
                                                    },
                                                    "metadata": {
                                                      "anyOf": [
                                                        {
                                                          "type": "object",
                                                          "propertyNames": {
                                                            "type": "string"
                                                          },
                                                          "additionalProperties": {}
                                                        },
                                                        {
                                                          "type": "null"
                                                        }
                                                      ]
                                                    },
                                                    "enabled": {
                                                      "type": "boolean"
                                                    },
                                                    "applicationId": {
                                                      "type": "number"
                                                    },
                                                    "evaluationParams": {
                                                      "type": "array",
                                                      "items": {
                                                        "type": "string",
                                                        "enum": [
                                                          "INPUT",
                                                          "ACTUAL_OUTPUT",
                                                          "EXPECTED_OUTPUT",
                                                          "CONTEXT",
                                                          "RETRIEVAL_CONTEXT",
                                                          "EXECUTION_CONTEXT"
                                                        ]
                                                      }
                                                    }
                                                  },
                                                  "required": [
                                                    "name",
                                                    "type",
                                                    "evaluationCriteria"
                                                  ]
                                                }
                                              ]
                                            }
                                          },
                                          "transition": {
                                            "description": "Transitions to other nodes based on evaluation results.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/checkAgentImport_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ]
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ]
                                            }
                                          },
                                          "cachePolicy": {
                                            "description": "Controls execution caching for this decision node across messages in a conversation. auto (default): cache result and use a lightweight guard evaluation to detect staleness. always: always use cached result until explicitly cleared. never: always re-evaluate all criteria every message (disables caching).",
                                            "type": "string",
                                            "enum": [
                                              "auto",
                                              "always",
                                              "never"
                                            ]
                                          },
                                          "selectionPolicy": {
                                            "description": "Controls which enabled criteria are evaluated each message. all (default): every enabled criterion runs. contextual: a lightweight router selects only the criteria relevant to the current input and conversation state; the rest are skipped. Skipped criteria are not evaluated, so their structuredData fields are absent downstream (route on them with the \"exists\"/\"notExists\" operators) and scores.mean reflects only the criteria that ran.",
                                            "type": "string",
                                            "enum": [
                                              "all",
                                              "contextual"
                                            ]
                                          },
                                          "alwaysRunCriteria": {
                                            "description": "Only used when selectionPolicy is \"contextual\": IDs of evaluation criteria that always run (they bypass the router); every other criterion is AI-selected per message. Use this to pin extractors whose structuredData a downstream node depends on. Ignored when selectionPolicy is \"all\".",
                                            "type": "array",
                                            "items": {
                                              "type": "string"
                                            }
                                          },
                                          "contextualSelectionPrompt": {
                                            "description": "Only used when selectionPolicy is \"contextual\": extra author guidance appended to the built-in router prompt to steer which criteria it picks (e.g. \"prefer running Consultar NFSe whenever the user mentions a nota fiscal, even indirectly\"). It augments the router — it does not replace its output contract or the safe fallback of running everything. Ignored when selectionPolicy is \"all\".",
                                            "type": "string"
                                          },
                                          "routingPolicy": {
                                            "description": "How many REASONINGS (criteria) may win the routing on this node per message. all (default): every matching conditional transition fires in parallel. bestReasoning: only the highest-scoring reasoning wins — ALL matched transitions whose condition is anchored on it fire (they are that reasoning's flow), everything anchored on other reasonings is suppressed. topReasonings: like bestReasoning but the best `maxReasonings` reasonings win. A matched transition is anchored on the highest-scoring criterion its condition references (via \"resultsById.<id>.score\" paths, at any nesting). Score ties between reasonings break by position in this node's evaluationCriteria list (earlier wins) — reorder the list to set priority. Matched transitions that reference NO criterion score (pure structuredData/context/state conditions) are outside the competition and always fire, like \"default\" and unconditional transitions. Criteria evaluation is unaffected — this arbitrates AFTER scoring, so it is the reliable way to get \"only one reasoning wins\" (independent per-criterion evaluations cannot be prompted into exclusivity).",
                                            "type": "string",
                                            "enum": [
                                              "all",
                                              "bestReasoning",
                                              "topReasonings"
                                            ]
                                          },
                                          "maxReasonings": {
                                            "description": "Only used when routingPolicy is \"topReasonings\": how many of the highest-scoring reasonings win the routing. Ignored for other policies (\"bestReasoning\" is exactly maxReasonings = 1).",
                                            "type": "integer",
                                            "minimum": 1,
                                            "maximum": 9007199254740991
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type",
                                          "evaluationCriteria",
                                          "transition"
                                        ]
                                      },
                                      {
                                        "oneOf": [
                                          {
                                            "type": "object",
                                            "properties": {
                                              "id": {
                                                "description": "Unique identifier for this node.",
                                                "type": "string"
                                              },
                                              "type": {
                                                "type": "string",
                                                "const": "action"
                                              },
                                              "label": {
                                                "description": "Human-readable label for this action node.",
                                                "type": "string"
                                              },
                                              "mode": {
                                                "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                "type": "string",
                                                "enum": [
                                                  "sync",
                                                  "async"
                                                ]
                                              },
                                              "outputVar": {
                                                "description": "Variable name to store the action output for use by downstream nodes.",
                                                "type": "string"
                                              },
                                              "transition": {
                                                "description": "Transitions to other nodes after this action completes.",
                                                "type": "array",
                                                "items": {
                                                  "type": "object",
                                                  "properties": {
                                                    "if": {
                                                      "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                      "$ref": "#/components/schemas/checkAgentImport_schema0"
                                                    },
                                                    "default": {
                                                      "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                      "type": "boolean"
                                                    },
                                                    "to": {
                                                      "type": "object",
                                                      "properties": {
                                                        "nodeId": {
                                                          "description": "The ID of the target node to transition to.",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "required": [
                                                        "nodeId"
                                                      ]
                                                    },
                                                    "stop": {
                                                      "description": "If true, stop execution after this transition.",
                                                      "type": "boolean"
                                                    }
                                                  },
                                                  "required": [
                                                    "to"
                                                  ]
                                                }
                                              },
                                              "actionType": {
                                                "type": "string",
                                                "const": "INSTRUCTIONS"
                                              },
                                              "config": {
                                                "type": "object",
                                                "properties": {
                                                  "instructions": {
                                                    "description": "The instructions for the LLM to execute.",
                                                    "type": "string"
                                                  },
                                                  "modelTier": {
                                                    "description": "The model tier to use for this instruction. Defaults to regular.",
                                                    "type": "string",
                                                    "enum": [
                                                      "lite",
                                                      "regular",
                                                      "pro"
                                                    ]
                                                  },
                                                  "thinkingEffortPct": {
                                                    "description": "Thinking effort percentage (0-100) controlling how much reasoning the model applies.",
                                                    "type": "number",
                                                    "minimum": 0,
                                                    "maximum": 100
                                                  },
                                                  "maxOutputTokens": {
                                                    "description": "Maximum tokens the model may generate for this node. On thinking models the budget is SHARED between reasoning and output — reasoning routinely consumes most of it — so a node whose structured output is truncated is usually better served by lowering thinkingEffortPct than by raising this. Defaults to the model maximum when omitted.",
                                                    "type": "integer",
                                                    "minimum": 1,
                                                    "maximum": 9007199254740991
                                                  },
                                                  "maxRetries": {
                                                    "description": "How many times this node retries a failed model call. Defaults to 2 when the node has an outputSchema and 5 otherwise. Raise it for nodes whose long outputs are exposed to dropped provider streams; it does not help failures the model reproduces deterministically.",
                                                    "type": "integer",
                                                    "minimum": 1,
                                                    "maximum": 10
                                                  },
                                                  "toolChoiceMode": {
                                                    "description": "Tool selection mode for this instruction. Defaults to auto when omitted.",
                                                    "type": "string",
                                                    "enum": [
                                                      "auto",
                                                      "none",
                                                      "tool",
                                                      "tools"
                                                    ]
                                                  },
                                                  "toolChoiceToolName": {
                                                    "description": "When toolChoiceMode is \"tool\", the specific tool name to force.",
                                                    "type": "string"
                                                  },
                                                  "toolChoiceToolNames": {
                                                    "description": "When toolChoiceMode is \"tools\", the list of allowed tool names.",
                                                    "type": "array",
                                                    "items": {
                                                      "type": "string"
                                                    }
                                                  },
                                                  "suppressTextResponse": {
                                                    "description": "When true, text output from the LLM is suppressed and only tool-call results are emitted. Useful when the instruction should only invoke tools (e.g., displayMedia) without generating follow-up text.",
                                                    "type": "boolean"
                                                  },
                                                  "stopAfterFirstToolCall": {
                                                    "description": "When true and a single tool is forced with text suppressed, the instruction stops after the first successful tool call. Defaults to false, which allows the tool to be called across multiple steps.",
                                                    "type": "boolean"
                                                  },
                                                  "internal": {
                                                    "description": "When true, this node is an intermediate step: its text/structured output is NOT shown to the user (not streamed, not persisted as a visible message part) and is only captured into the node's outputVar for downstream nodes. Reasoning and tool-call activity chips remain visible. Use for internal hand-offs (e.g. tool-driven data synthesis a later node consumes); the user-facing reply should come from a later, non-internal node.",
                                                    "type": "boolean"
                                                  },
                                                  "outputSchema": {
                                                    "description": "JSON Schema for structured output. When provided, the LLM will output valid JSON matching this schema instead of free-form text.",
                                                    "type": "object",
                                                    "properties": {
                                                      "type": {
                                                        "description": "JSON Schema type, must be \"object\" for structured output.",
                                                        "type": "string",
                                                        "const": "object"
                                                      },
                                                      "properties": {
                                                        "description": "Schema properties defining the expected output structure.",
                                                        "type": "object",
                                                        "propertyNames": {
                                                          "type": "string"
                                                        },
                                                        "additionalProperties": {}
                                                      },
                                                      "required": {
                                                        "description": "Array of required property names.",
                                                        "type": "array",
                                                        "items": {
                                                          "type": "string"
                                                        }
                                                      },
                                                      "additionalProperties": {
                                                        "description": "Whether to allow additional properties not defined in the schema.",
                                                        "type": "boolean"
                                                      },
                                                      "description": {
                                                        "description": "Description of the expected output to guide the LLM.",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "type",
                                                      "properties"
                                                    ]
                                                  },
                                                  "grounding": {
                                                    "description": "Model-side grounding for this node. Only Google Search is available today.",
                                                    "type": "object",
                                                    "properties": {
                                                      "googleSearch": {
                                                        "description": "Enable Google Search grounding: the model searches the public web (via Gemini's built-in google_search tool) while executing this instruction and answers from what it finds. Set `{}` to enable with defaults. The node result then carries `grounding` — the queries Google ran and the sources it cited, each with the resolved article URL, its domain and the passages of the reply it supports — readable downstream as `nodes.<nodeId>.grounding` in javascript nodes and templates; the text/JSON reply itself still flows through outputVar as usual. With an outputSchema the search runs first and the JSON is synthesized afterwards with the numbered source list, so declare a `sourceIds` or `url` field if you want citations inside the structured output. Incompatible with toolChoiceMode \"tool\" and with suppressTextResponse (a forced tool call and Google Search in one request returns an empty reply); with toolChoiceMode \"none\" the node still searches but calls no other tool. Each prompt costs Google one search query per query the model decides to run (usually 4–10), billed per query beyond the project's free tier.",
                                                        "type": "object",
                                                        "properties": {
                                                          "excludeDomains": {
                                                            "description": "Domains Google Search must not ground on, e.g. [\"youtube.com\", \"reddit.com\"]. A domain excludes its subdomains too.",
                                                            "type": "array",
                                                            "items": {
                                                              "type": "string"
                                                            }
                                                          }
                                                        }
                                                      }
                                                    }
                                                  },
                                                  "urlContext": {
                                                    "description": "Gemini URL context: hand the model a list of URLs to READ IN FULL server-side instead of fetching their text into a variable first. The URLs come from the fixed \"urls\" list, from the \"from\" value path, or from both (fixed first). They are appended to the end of the instruction and the provider fetches and reads the pages inside the same call. With an outputSchema the node runs as a SINGLE call (reading and synthesis must share it), so pair it with toolChoiceMode \"none\" unless the node truly needs function tools. Limits: 20 URLs per call (extra ones are dropped and reported as `truncated`), public pages only — paywalls, Google News redirect links and private hosts fail. The model may skip fetching when the URLs sit inside a very long prompt, so prefer a dedicated short reading node over bolting URLs onto a large synthesis prompt. The node output carries `urlContext.{requested,retrieved,unread,truncated,invalid,unresolved,supported,tokens}`. `unread` is the integrity signal — it lists every URL the model did not read, including the ones dropped by the 20-URL cap — so branch on `nodes.<id>.urlContext.unread` for a fallback reader (inside a forEach body it holds only the last item). `unresolved` says the \"from\" path resolved to nothing, `invalid` lists entries that were not http(s) URLs, and `supported` is false when the model could not carry the tool: in those cases nothing was read at all. Retrieved page content is billed as input tokens and added to the node usage as `urlContextTokens`. Gemini 3+ models only.",
                                                    "type": "object",
                                                    "properties": {
                                                      "urls": {
                                                        "description": "Fixed http(s) URLs to read on every run, written out here — for pages that do not change per execution (a status page, a policy, a price list). Combine with \"from\" to read a fixed set plus whatever the run produced; the two lists concatenate, fixed URLs first.",
                                                        "type": "array",
                                                        "items": {
                                                          "type": "string"
                                                        }
                                                      },
                                                      "from": {
                                                        "description": "Dotted VALUE PATH (same resolution as forEach \"over\": workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — e.g. \"paraLer.soUrls\" or \"nodes.pick.result.urls\") to a URL list the run produced: an array of http(s) URL strings, a single URL string, or a JSON-encoded array string. Not a Handlebars template; a path wrapped in {{ }} is accepted and unwrapped.",
                                                        "type": "string",
                                                        "minLength": 1
                                                      }
                                                    }
                                                  }
                                                },
                                                "required": [
                                                  "instructions"
                                                ]
                                              }
                                            },
                                            "required": [
                                              "id",
                                              "type",
                                              "mode",
                                              "transition",
                                              "actionType",
                                              "config"
                                            ]
                                          },
                                          {
                                            "type": "object",
                                            "properties": {
                                              "id": {
                                                "description": "Unique identifier for this node.",
                                                "type": "string"
                                              },
                                              "type": {
                                                "type": "string",
                                                "const": "action"
                                              },
                                              "label": {
                                                "description": "Human-readable label for this action node.",
                                                "type": "string"
                                              },
                                              "mode": {
                                                "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                "type": "string",
                                                "enum": [
                                                  "sync",
                                                  "async"
                                                ]
                                              },
                                              "outputVar": {
                                                "description": "Variable name to store the action output for use by downstream nodes.",
                                                "type": "string"
                                              },
                                              "transition": {
                                                "description": "Transitions to other nodes after this action completes.",
                                                "type": "array",
                                                "items": {
                                                  "type": "object",
                                                  "properties": {
                                                    "if": {
                                                      "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                      "$ref": "#/components/schemas/checkAgentImport_schema0"
                                                    },
                                                    "default": {
                                                      "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                      "type": "boolean"
                                                    },
                                                    "to": {
                                                      "type": "object",
                                                      "properties": {
                                                        "nodeId": {
                                                          "description": "The ID of the target node to transition to.",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "required": [
                                                        "nodeId"
                                                      ]
                                                    },
                                                    "stop": {
                                                      "description": "If true, stop execution after this transition.",
                                                      "type": "boolean"
                                                    }
                                                  },
                                                  "required": [
                                                    "to"
                                                  ]
                                                }
                                              },
                                              "actionType": {
                                                "type": "string",
                                                "const": "EMAIL"
                                              },
                                              "config": {
                                                "type": "object",
                                                "properties": {
                                                  "to": {
                                                    "type": "string"
                                                  },
                                                  "senderType": {
                                                    "type": "string",
                                                    "enum": [
                                                      "default",
                                                      "gmail"
                                                    ]
                                                  },
                                                  "gmailIntegrationId": {
                                                    "type": "string"
                                                  },
                                                  "subject": {
                                                    "type": "string"
                                                  },
                                                  "body": {
                                                    "type": "string"
                                                  },
                                                  "cc": {
                                                    "type": "string"
                                                  },
                                                  "bcc": {
                                                    "type": "string"
                                                  },
                                                  "attachments": {
                                                    "type": "array",
                                                    "items": {
                                                      "type": "object",
                                                      "properties": {
                                                        "documentId": {
                                                          "type": "number"
                                                        },
                                                        "url": {
                                                          "type": "string"
                                                        },
                                                        "filename": {
                                                          "type": "string"
                                                        }
                                                      }
                                                    }
                                                  },
                                                  "templateId": {
                                                    "type": "string"
                                                  },
                                                  "templateName": {
                                                    "type": "string"
                                                  },
                                                  "applicationId": {
                                                    "type": "number"
                                                  }
                                                },
                                                "required": [
                                                  "to",
                                                  "subject",
                                                  "body"
                                                ]
                                              }
                                            },
                                            "required": [
                                              "id",
                                              "type",
                                              "mode",
                                              "transition",
                                              "actionType",
                                              "config"
                                            ]
                                          },
                                          {
                                            "type": "object",
                                            "properties": {
                                              "id": {
                                                "description": "Unique identifier for this node.",
                                                "type": "string"
                                              },
                                              "type": {
                                                "type": "string",
                                                "const": "action"
                                              },
                                              "label": {
                                                "description": "Human-readable label for this action node.",
                                                "type": "string"
                                              },
                                              "mode": {
                                                "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                "type": "string",
                                                "enum": [
                                                  "sync",
                                                  "async"
                                                ]
                                              },
                                              "outputVar": {
                                                "description": "Variable name to store the action output for use by downstream nodes.",
                                                "type": "string"
                                              },
                                              "transition": {
                                                "description": "Transitions to other nodes after this action completes.",
                                                "type": "array",
                                                "items": {
                                                  "type": "object",
                                                  "properties": {
                                                    "if": {
                                                      "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                      "$ref": "#/components/schemas/checkAgentImport_schema0"
                                                    },
                                                    "default": {
                                                      "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                      "type": "boolean"
                                                    },
                                                    "to": {
                                                      "type": "object",
                                                      "properties": {
                                                        "nodeId": {
                                                          "description": "The ID of the target node to transition to.",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "required": [
                                                        "nodeId"
                                                      ]
                                                    },
                                                    "stop": {
                                                      "description": "If true, stop execution after this transition.",
                                                      "type": "boolean"
                                                    }
                                                  },
                                                  "required": [
                                                    "to"
                                                  ]
                                                }
                                              },
                                              "actionType": {
                                                "type": "string",
                                                "const": "WEBHOOK"
                                              },
                                              "config": {
                                                "type": "object",
                                                "properties": {
                                                  "url": {
                                                    "type": "string"
                                                  },
                                                  "method": {
                                                    "type": "string",
                                                    "enum": [
                                                      "GET",
                                                      "POST",
                                                      "PUT",
                                                      "PATCH",
                                                      "DELETE"
                                                    ]
                                                  },
                                                  "headers": {
                                                    "type": "object",
                                                    "propertyNames": {
                                                      "type": "string"
                                                    },
                                                    "additionalProperties": {
                                                      "type": "string"
                                                    }
                                                  },
                                                  "queryParams": {
                                                    "type": "object",
                                                    "propertyNames": {
                                                      "type": "string"
                                                    },
                                                    "additionalProperties": {
                                                      "type": "string"
                                                    }
                                                  },
                                                  "body": {
                                                    "type": "string"
                                                  },
                                                  "timeout": {
                                                    "type": "number"
                                                  },
                                                  "responseMode": {
                                                    "description": "How to decode the response body. \"json\" (default): parse as JSON/text and expose via varsDelta. \"attachment\": read as binary bytes for multimodal input (e.g. PDFs, images).",
                                                    "type": "string",
                                                    "enum": [
                                                      "json",
                                                      "attachment"
                                                    ]
                                                  },
                                                  "asMessage": {
                                                    "description": "When true, append the response to the conversation as a new user message so downstream LLM nodes see it. In \"attachment\" mode the message carries a file content part; in \"json\" mode it carries the stringified body as text. Defaults to false — preserving the historical behavior where webhook responses only flow through varsDelta.",
                                                    "type": "boolean"
                                                  },
                                                  "suppressNoResponseFallback": {
                                                    "description": "Marks the webhook as a fire-and-forget trigger: the conversation is meant to end here, with the rest happening on the receiving system. When the call succeeds and the turn finishes without sending anything to the user, the channel skips its automatic \"sorry, something went wrong\" fallback message. A failed call (HTTP >= 400) still gets the fallback, since the user is then left waiting for nothing.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "url",
                                                  "method"
                                                ]
                                              }
                                            },
                                            "required": [
                                              "id",
                                              "type",
                                              "mode",
                                              "transition",
                                              "actionType",
                                              "config"
                                            ]
                                          },
                                          {
                                            "type": "object",
                                            "properties": {
                                              "id": {
                                                "description": "Unique identifier for this node.",
                                                "type": "string"
                                              },
                                              "type": {
                                                "type": "string",
                                                "const": "action"
                                              },
                                              "label": {
                                                "description": "Human-readable label for this action node.",
                                                "type": "string"
                                              },
                                              "mode": {
                                                "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                "type": "string",
                                                "enum": [
                                                  "sync",
                                                  "async"
                                                ]
                                              },
                                              "outputVar": {
                                                "description": "Variable name to store the action output for use by downstream nodes.",
                                                "type": "string"
                                              },
                                              "transition": {
                                                "description": "Transitions to other nodes after this action completes.",
                                                "type": "array",
                                                "items": {
                                                  "type": "object",
                                                  "properties": {
                                                    "if": {
                                                      "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                      "$ref": "#/components/schemas/checkAgentImport_schema0"
                                                    },
                                                    "default": {
                                                      "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                      "type": "boolean"
                                                    },
                                                    "to": {
                                                      "type": "object",
                                                      "properties": {
                                                        "nodeId": {
                                                          "description": "The ID of the target node to transition to.",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "required": [
                                                        "nodeId"
                                                      ]
                                                    },
                                                    "stop": {
                                                      "description": "If true, stop execution after this transition.",
                                                      "type": "boolean"
                                                    }
                                                  },
                                                  "required": [
                                                    "to"
                                                  ]
                                                }
                                              },
                                              "actionType": {
                                                "type": "string",
                                                "const": "DOCUMENT_TEMPLATE"
                                              },
                                              "config": {
                                                "type": "object",
                                                "properties": {
                                                  "templateId": {
                                                    "type": "string"
                                                  },
                                                  "templateName": {
                                                    "type": "string"
                                                  },
                                                  "sendEmail": {
                                                    "type": "boolean"
                                                  },
                                                  "sendWhatsApp": {
                                                    "type": "boolean"
                                                  },
                                                  "recipientEmail": {
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "templateId"
                                                ]
                                              }
                                            },
                                            "required": [
                                              "id",
                                              "type",
                                              "mode",
                                              "transition",
                                              "actionType",
                                              "config"
                                            ]
                                          },
                                          {
                                            "type": "object",
                                            "properties": {
                                              "id": {
                                                "description": "Unique identifier for this node.",
                                                "type": "string"
                                              },
                                              "type": {
                                                "type": "string",
                                                "const": "action"
                                              },
                                              "label": {
                                                "description": "Human-readable label for this action node.",
                                                "type": "string"
                                              },
                                              "mode": {
                                                "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                "type": "string",
                                                "enum": [
                                                  "sync",
                                                  "async"
                                                ]
                                              },
                                              "outputVar": {
                                                "description": "Variable name to store the action output for use by downstream nodes.",
                                                "type": "string"
                                              },
                                              "transition": {
                                                "description": "Transitions to other nodes after this action completes.",
                                                "type": "array",
                                                "items": {
                                                  "type": "object",
                                                  "properties": {
                                                    "if": {
                                                      "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                      "$ref": "#/components/schemas/checkAgentImport_schema0"
                                                    },
                                                    "default": {
                                                      "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                      "type": "boolean"
                                                    },
                                                    "to": {
                                                      "type": "object",
                                                      "properties": {
                                                        "nodeId": {
                                                          "description": "The ID of the target node to transition to.",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "required": [
                                                        "nodeId"
                                                      ]
                                                    },
                                                    "stop": {
                                                      "description": "If true, stop execution after this transition.",
                                                      "type": "boolean"
                                                    }
                                                  },
                                                  "required": [
                                                    "to"
                                                  ]
                                                }
                                              },
                                              "actionType": {
                                                "type": "string",
                                                "const": "TOOL_CALL"
                                              },
                                              "config": {
                                                "type": "object",
                                                "properties": {
                                                  "toolName": {
                                                    "description": "The name of the common tool to invoke.",
                                                    "type": "string"
                                                  },
                                                  "parameters": {
                                                    "description": "Per-parameter configuration. Keys are parameter names from the tool schema.",
                                                    "type": "object",
                                                    "propertyNames": {
                                                      "type": "string"
                                                    },
                                                    "additionalProperties": {
                                                      "type": "object",
                                                      "properties": {
                                                        "mode": {
                                                          "description": "Whether this parameter is hardcoded (static) or filled by the LLM at runtime (dynamic).",
                                                          "type": "string",
                                                          "enum": [
                                                            "static",
                                                            "dynamic"
                                                          ]
                                                        },
                                                        "staticValue": {
                                                          "description": "The fixed value for this parameter. Required when mode is \"static\"."
                                                        },
                                                        "instructions": {
                                                          "description": "Optional guidance for the LLM when filling this parameter (only used when mode is \"dynamic\").",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "required": [
                                                        "mode"
                                                      ]
                                                    }
                                                  },
                                                  "instructions": {
                                                    "description": "General instructions for the LLM when resolving dynamic parameters.",
                                                    "type": "string"
                                                  },
                                                  "skipKnowledgeSearch": {
                                                    "description": "When a node has dynamic parameters, the model is normally forced to call similaritySearch first so parameter values are grounded in the knowledge base, costing one extra model round. Set true for tools that need no knowledge context (for example code execution) to call the configured tool directly. Ignored when every parameter is static, since no model runs at all.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "toolName"
                                                ]
                                              }
                                            },
                                            "required": [
                                              "id",
                                              "type",
                                              "mode",
                                              "transition",
                                              "actionType",
                                              "config"
                                            ]
                                          },
                                          {
                                            "type": "object",
                                            "properties": {
                                              "id": {
                                                "description": "Unique identifier for this node.",
                                                "type": "string"
                                              },
                                              "type": {
                                                "type": "string",
                                                "const": "action"
                                              },
                                              "label": {
                                                "description": "Human-readable label for this action node.",
                                                "type": "string"
                                              },
                                              "mode": {
                                                "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                "type": "string",
                                                "enum": [
                                                  "sync",
                                                  "async"
                                                ]
                                              },
                                              "outputVar": {
                                                "description": "Variable name to store the action output for use by downstream nodes.",
                                                "type": "string"
                                              },
                                              "transition": {
                                                "description": "Transitions to other nodes after this action completes.",
                                                "type": "array",
                                                "items": {
                                                  "type": "object",
                                                  "properties": {
                                                    "if": {
                                                      "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                      "$ref": "#/components/schemas/checkAgentImport_schema0"
                                                    },
                                                    "default": {
                                                      "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                      "type": "boolean"
                                                    },
                                                    "to": {
                                                      "type": "object",
                                                      "properties": {
                                                        "nodeId": {
                                                          "description": "The ID of the target node to transition to.",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "required": [
                                                        "nodeId"
                                                      ]
                                                    },
                                                    "stop": {
                                                      "description": "If true, stop execution after this transition.",
                                                      "type": "boolean"
                                                    }
                                                  },
                                                  "required": [
                                                    "to"
                                                  ]
                                                }
                                              },
                                              "actionType": {
                                                "type": "string",
                                                "const": "FOLLOW_UP"
                                              },
                                              "config": {
                                                "type": "object",
                                                "properties": {
                                                  "delayMinutes": {
                                                    "description": "Minutes to wait before checking whether to run the inner action. Common presets: 5, 10, 15. Maximum 1440 (24h). Cloud Scheduler is cron-based so the actual fire time is rounded to the next minute boundary.",
                                                    "type": "integer",
                                                    "minimum": 1,
                                                    "maximum": 1440
                                                  },
                                                  "cancelOnUserMessage": {
                                                    "description": "When true (default), skip the inner action if any USER message arrived after the node was reached. Set to false only if the follow-up should fire even after the user has replied.",
                                                    "type": "boolean"
                                                  },
                                                  "cancelOnAssistantMessage": {
                                                    "description": "When true (default), skip the inner action if any ASSISTANT text message was sent after the node was reached. Tool-only assistant messages (no text content) do NOT count. Prevents double-pinging when another node already produced a response.",
                                                    "type": "boolean"
                                                  },
                                                  "cancelOnArchive": {
                                                    "description": "When true (default), skip the inner action if the thread was archived between scheduling and firing.",
                                                    "type": "boolean"
                                                  },
                                                  "action": {
                                                    "description": "The inner action to run when the delay elapses and cancel rules pass. INSTRUCTIONS produces an LLM-generated text message (good for \"Are you still there?\"-style nudges). TOOL_CALL fires a display tool (good for offering options or showing media).",
                                                    "oneOf": [
                                                      {
                                                        "type": "object",
                                                        "properties": {
                                                          "actionType": {
                                                            "type": "string",
                                                            "const": "INSTRUCTIONS"
                                                          },
                                                          "config": {
                                                            "type": "object",
                                                            "properties": {
                                                              "instructions": {
                                                                "description": "The instructions for the LLM to execute.",
                                                                "type": "string"
                                                              },
                                                              "modelTier": {
                                                                "description": "The model tier to use for this instruction. Defaults to regular.",
                                                                "type": "string",
                                                                "enum": [
                                                                  "lite",
                                                                  "regular",
                                                                  "pro"
                                                                ]
                                                              },
                                                              "thinkingEffortPct": {
                                                                "description": "Thinking effort percentage (0-100) controlling how much reasoning the model applies.",
                                                                "type": "number",
                                                                "minimum": 0,
                                                                "maximum": 100
                                                              },
                                                              "maxOutputTokens": {
                                                                "description": "Maximum tokens the model may generate for this node. On thinking models the budget is SHARED between reasoning and output — reasoning routinely consumes most of it — so a node whose structured output is truncated is usually better served by lowering thinkingEffortPct than by raising this. Defaults to the model maximum when omitted.",
                                                                "type": "integer",
                                                                "minimum": 1,
                                                                "maximum": 9007199254740991
                                                              },
                                                              "maxRetries": {
                                                                "description": "How many times this node retries a failed model call. Defaults to 2 when the node has an outputSchema and 5 otherwise. Raise it for nodes whose long outputs are exposed to dropped provider streams; it does not help failures the model reproduces deterministically.",
                                                                "type": "integer",
                                                                "minimum": 1,
                                                                "maximum": 10
                                                              },
                                                              "toolChoiceMode": {
                                                                "description": "Tool selection mode for this instruction. Defaults to auto when omitted.",
                                                                "type": "string",
                                                                "enum": [
                                                                  "auto",
                                                                  "none",
                                                                  "tool",
                                                                  "tools"
                                                                ]
                                                              },
                                                              "toolChoiceToolName": {
                                                                "description": "When toolChoiceMode is \"tool\", the specific tool name to force.",
                                                                "type": "string"
                                                              },
                                                              "toolChoiceToolNames": {
                                                                "description": "When toolChoiceMode is \"tools\", the list of allowed tool names.",
                                                                "type": "array",
                                                                "items": {
                                                                  "type": "string"
                                                                }
                                                              },
                                                              "suppressTextResponse": {
                                                                "description": "When true, text output from the LLM is suppressed and only tool-call results are emitted. Useful when the instruction should only invoke tools (e.g., displayMedia) without generating follow-up text.",
                                                                "type": "boolean"
                                                              },
                                                              "stopAfterFirstToolCall": {
                                                                "description": "When true and a single tool is forced with text suppressed, the instruction stops after the first successful tool call. Defaults to false, which allows the tool to be called across multiple steps.",
                                                                "type": "boolean"
                                                              },
                                                              "internal": {
                                                                "description": "When true, this node is an intermediate step: its text/structured output is NOT shown to the user (not streamed, not persisted as a visible message part) and is only captured into the node's outputVar for downstream nodes. Reasoning and tool-call activity chips remain visible. Use for internal hand-offs (e.g. tool-driven data synthesis a later node consumes); the user-facing reply should come from a later, non-internal node.",
                                                                "type": "boolean"
                                                              },
                                                              "outputSchema": {
                                                                "description": "JSON Schema for structured output. When provided, the LLM will output valid JSON matching this schema instead of free-form text.",
                                                                "type": "object",
                                                                "properties": {
                                                                  "type": {
                                                                    "description": "JSON Schema type, must be \"object\" for structured output.",
                                                                    "type": "string",
                                                                    "const": "object"
                                                                  },
                                                                  "properties": {
                                                                    "description": "Schema properties defining the expected output structure.",
                                                                    "type": "object",
                                                                    "propertyNames": {
                                                                      "type": "string"
                                                                    },
                                                                    "additionalProperties": {}
                                                                  },
                                                                  "required": {
                                                                    "description": "Array of required property names.",
                                                                    "type": "array",
                                                                    "items": {
                                                                      "type": "string"
                                                                    }
                                                                  },
                                                                  "additionalProperties": {
                                                                    "description": "Whether to allow additional properties not defined in the schema.",
                                                                    "type": "boolean"
                                                                  },
                                                                  "description": {
                                                                    "description": "Description of the expected output to guide the LLM.",
                                                                    "type": "string"
                                                                  }
                                                                },
                                                                "required": [
                                                                  "type",
                                                                  "properties"
                                                                ]
                                                              },
                                                              "grounding": {
                                                                "description": "Model-side grounding for this node. Only Google Search is available today.",
                                                                "type": "object",
                                                                "properties": {
                                                                  "googleSearch": {
                                                                    "description": "Enable Google Search grounding: the model searches the public web (via Gemini's built-in google_search tool) while executing this instruction and answers from what it finds. Set `{}` to enable with defaults. The node result then carries `grounding` — the queries Google ran and the sources it cited, each with the resolved article URL, its domain and the passages of the reply it supports — readable downstream as `nodes.<nodeId>.grounding` in javascript nodes and templates; the text/JSON reply itself still flows through outputVar as usual. With an outputSchema the search runs first and the JSON is synthesized afterwards with the numbered source list, so declare a `sourceIds` or `url` field if you want citations inside the structured output. Incompatible with toolChoiceMode \"tool\" and with suppressTextResponse (a forced tool call and Google Search in one request returns an empty reply); with toolChoiceMode \"none\" the node still searches but calls no other tool. Each prompt costs Google one search query per query the model decides to run (usually 4–10), billed per query beyond the project's free tier.",
                                                                    "type": "object",
                                                                    "properties": {
                                                                      "excludeDomains": {
                                                                        "description": "Domains Google Search must not ground on, e.g. [\"youtube.com\", \"reddit.com\"]. A domain excludes its subdomains too.",
                                                                        "type": "array",
                                                                        "items": {
                                                                          "type": "string"
                                                                        }
                                                                      }
                                                                    }
                                                                  }
                                                                }
                                                              },
                                                              "urlContext": {
                                                                "description": "Gemini URL context: hand the model a list of URLs to READ IN FULL server-side instead of fetching their text into a variable first. The URLs come from the fixed \"urls\" list, from the \"from\" value path, or from both (fixed first). They are appended to the end of the instruction and the provider fetches and reads the pages inside the same call. With an outputSchema the node runs as a SINGLE call (reading and synthesis must share it), so pair it with toolChoiceMode \"none\" unless the node truly needs function tools. Limits: 20 URLs per call (extra ones are dropped and reported as `truncated`), public pages only — paywalls, Google News redirect links and private hosts fail. The model may skip fetching when the URLs sit inside a very long prompt, so prefer a dedicated short reading node over bolting URLs onto a large synthesis prompt. The node output carries `urlContext.{requested,retrieved,unread,truncated,invalid,unresolved,supported,tokens}`. `unread` is the integrity signal — it lists every URL the model did not read, including the ones dropped by the 20-URL cap — so branch on `nodes.<id>.urlContext.unread` for a fallback reader (inside a forEach body it holds only the last item). `unresolved` says the \"from\" path resolved to nothing, `invalid` lists entries that were not http(s) URLs, and `supported` is false when the model could not carry the tool: in those cases nothing was read at all. Retrieved page content is billed as input tokens and added to the node usage as `urlContextTokens`. Gemini 3+ models only.",
                                                                "type": "object",
                                                                "properties": {
                                                                  "urls": {
                                                                    "description": "Fixed http(s) URLs to read on every run, written out here — for pages that do not change per execution (a status page, a policy, a price list). Combine with \"from\" to read a fixed set plus whatever the run produced; the two lists concatenate, fixed URLs first.",
                                                                    "type": "array",
                                                                    "items": {
                                                                      "type": "string"
                                                                    }
                                                                  },
                                                                  "from": {
                                                                    "description": "Dotted VALUE PATH (same resolution as forEach \"over\": workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — e.g. \"paraLer.soUrls\" or \"nodes.pick.result.urls\") to a URL list the run produced: an array of http(s) URL strings, a single URL string, or a JSON-encoded array string. Not a Handlebars template; a path wrapped in {{ }} is accepted and unwrapped.",
                                                                    "type": "string",
                                                                    "minLength": 1
                                                                  }
                                                                }
                                                              }
                                                            },
                                                            "required": [
                                                              "instructions"
                                                            ]
                                                          }
                                                        },
                                                        "required": [
                                                          "actionType",
                                                          "config"
                                                        ]
                                                      },
                                                      {
                                                        "type": "object",
                                                        "properties": {
                                                          "actionType": {
                                                            "type": "string",
                                                            "const": "TOOL_CALL"
                                                          },
                                                          "config": {
                                                            "type": "object",
                                                            "properties": {
                                                              "toolName": {
                                                                "description": "The name of the common tool to invoke.",
                                                                "type": "string"
                                                              },
                                                              "parameters": {
                                                                "description": "Per-parameter configuration. Keys are parameter names from the tool schema.",
                                                                "type": "object",
                                                                "propertyNames": {
                                                                  "type": "string"
                                                                },
                                                                "additionalProperties": {
                                                                  "type": "object",
                                                                  "properties": {
                                                                    "mode": {
                                                                      "description": "Whether this parameter is hardcoded (static) or filled by the LLM at runtime (dynamic).",
                                                                      "type": "string",
                                                                      "enum": [
                                                                        "static",
                                                                        "dynamic"
                                                                      ]
                                                                    },
                                                                    "staticValue": {
                                                                      "description": "The fixed value for this parameter. Required when mode is \"static\"."
                                                                    },
                                                                    "instructions": {
                                                                      "description": "Optional guidance for the LLM when filling this parameter (only used when mode is \"dynamic\").",
                                                                      "type": "string"
                                                                    }
                                                                  },
                                                                  "required": [
                                                                    "mode"
                                                                  ]
                                                                }
                                                              },
                                                              "instructions": {
                                                                "description": "General instructions for the LLM when resolving dynamic parameters.",
                                                                "type": "string"
                                                              },
                                                              "skipKnowledgeSearch": {
                                                                "description": "When a node has dynamic parameters, the model is normally forced to call similaritySearch first so parameter values are grounded in the knowledge base, costing one extra model round. Set true for tools that need no knowledge context (for example code execution) to call the configured tool directly. Ignored when every parameter is static, since no model runs at all.",
                                                                "type": "boolean"
                                                              }
                                                            },
                                                            "required": [
                                                              "toolName"
                                                            ]
                                                          }
                                                        },
                                                        "required": [
                                                          "actionType",
                                                          "config"
                                                        ]
                                                      }
                                                    ]
                                                  }
                                                },
                                                "required": [
                                                  "delayMinutes",
                                                  "action"
                                                ]
                                              }
                                            },
                                            "required": [
                                              "id",
                                              "type",
                                              "mode",
                                              "transition",
                                              "actionType",
                                              "config"
                                            ]
                                          }
                                        ]
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "subAgent"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this sub-agent node.",
                                            "type": "string"
                                          },
                                          "agentId": {
                                            "description": "The ID of the sub-agent to invoke.",
                                            "type": "string"
                                          },
                                          "instructions": {
                                            "description": "Optional instructions message prepended to the sub-agent conversation. Supports Handlebars interpolation against the parent execution scope: `{{var}}` reads workflow vars, `{{context.x}}` reads contextVars, `{{env.X}}` reads environment, `{{input.text}}` reads the original user input, and `{{nodes.<id>.<path>}}` reads prior node outputs.",
                                            "type": "string"
                                          },
                                          "transition": {
                                            "description": "Optional transitions to continue the flow after the sub-agent returns.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/checkAgentImport_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ]
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ]
                                            }
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type",
                                          "agentId"
                                        ]
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "end"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this end node.",
                                            "type": "string"
                                          },
                                          "config": {
                                            "description": "Optional configuration for the end node behavior.",
                                            "type": "object",
                                            "properties": {
                                              "resetConversationHistory": {
                                                "description": "If true, the next user message starts a new conversation with no prior history.",
                                                "type": "boolean"
                                              }
                                            }
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type"
                                        ]
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "state"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this state node.",
                                            "type": "string"
                                          },
                                          "outputVar": {
                                            "description": "Agent-scope get only: variable name that receives the value stored under `config.key` (null when the key has never been written). Downstream templates read it as `{{<outputVar>}}`; transition conditions as `{source:\"vars\", path:\"<outputVar>...\"}`.",
                                            "type": "string"
                                          },
                                          "config": {
                                            "type": "object",
                                            "properties": {
                                              "scope": {
                                                "description": "How long the data lives and who sees it. execution: this run only. session: this conversation (thread) — a NEW conversation starts empty. agent: durable memory shared by every execution of this agent, across conversations — use it to remember things between independent runs. Survives clearCache.",
                                                "type": "string",
                                                "enum": [
                                                  "execution",
                                                  "session",
                                                  "agent"
                                                ]
                                              },
                                              "operation": {
                                                "description": "Agent scope only (default set). set: durably store the `state` entries. get: read the entry under `key` into `outputVar`. Execution/session scopes are always set — their values are injected into templates automatically, so no get is needed.",
                                                "type": "string",
                                                "enum": [
                                                  "set",
                                                  "get"
                                                ]
                                              },
                                              "key": {
                                                "description": "Agent-scope get: the memory key to read. Supports Handlebars (e.g. \"evidence-{{context.cnpj}}\") so one node can address per-entity entries. Rendered keys are limited to 512 characters.",
                                                "type": "string"
                                              },
                                              "state": {
                                                "description": "Key-value pairs to set (required for set operations). String values support Handlebars. In agent scope the KEYS are templates too (e.g. \"evidence-{{context.cnpj}}\"), each entry is stored as its own durable row, and serialized values are size-capped.",
                                                "type": "object",
                                                "propertyNames": {
                                                  "type": "string"
                                                },
                                                "additionalProperties": {}
                                              }
                                            },
                                            "required": [
                                              "scope"
                                            ]
                                          },
                                          "transition": {
                                            "description": "Optional transitions to continue the flow after setting state.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/checkAgentImport_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ]
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ]
                                            }
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type",
                                          "config"
                                        ]
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "hub"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this hub node.",
                                            "type": "string"
                                          },
                                          "transition": {
                                            "description": "Transitions to route connections to other nodes.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/checkAgentImport_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ]
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ]
                                            }
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type"
                                        ]
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "jump"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this jump node.",
                                            "type": "string"
                                          },
                                          "transition": {
                                            "description": "Target node to jump to unconditionally.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/checkAgentImport_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ]
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ]
                                            }
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type"
                                        ]
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "clearCache"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this clear cache node.",
                                            "type": "string"
                                          },
                                          "config": {
                                            "description": "Optional configuration controlling what is cleared.",
                                            "type": "object",
                                            "properties": {
                                              "clearScope": {
                                                "description": "What to clear. executionCache (default): clears only the decision result cache. all: clears the entire session state including user-defined session variables.",
                                                "type": "string",
                                                "enum": [
                                                  "executionCache",
                                                  "all"
                                                ]
                                              }
                                            }
                                          },
                                          "transition": {
                                            "description": "Optional transitions to continue the flow after clearing cache.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/checkAgentImport_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ]
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ]
                                            }
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type"
                                        ]
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "javascript"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this JavaScript node.",
                                            "type": "string"
                                          },
                                          "outputVar": {
                                            "description": "Variable name to store the returned value for downstream nodes. Downstream templates read it as `{{<outputVar>}}`; transition conditions as `{source:\"vars\", path:\"<outputVar>...\"}`.",
                                            "type": "string"
                                          },
                                          "config": {
                                            "type": "object",
                                            "properties": {
                                              "code": {
                                                "description": "JavaScript source executed in a sandboxed QuickJS interpreter. Written as a function body: it receives ({ vars, evaluation, context, env, input, nodes }) and must `return` a JSON-serializable value. Synchronous only — no network, filesystem, require/import, or timers.",
                                                "type": "string"
                                              },
                                              "timeoutMs": {
                                                "description": "CPU deadline in milliseconds. Default 1000, max 10000.",
                                                "type": "integer",
                                                "minimum": 1,
                                                "maximum": 10000
                                              }
                                            },
                                            "required": [
                                              "code"
                                            ]
                                          },
                                          "transition": {
                                            "description": "Optional transitions to continue the flow after the code runs.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/checkAgentImport_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ]
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ]
                                            }
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type",
                                          "config"
                                        ]
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "forEach"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this forEach node.",
                                            "type": "string"
                                          },
                                          "over": {
                                            "description": "Dotted path to the array to iterate, resolved against the execution scope: top-level workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — for example \"research.socioAlvos\" or \"nodes.build_plan.result.targets\". This is a VALUE PATH, not a Handlebars template: Handlebars renders to a string, so an array passed through it would arrive as \"[object Object]\". A path wrapped in {{ }} is accepted and unwrapped. If the path does not resolve to an array the node fails loudly instead of iterating a string.",
                                            "type": "string"
                                          },
                                          "as": {
                                            "description": "Variable name bound to the current element inside the body node: \"socio\" makes {{socio.nome}} available to the body's templates. Must not be \"iteration\", which is reserved for the {index, total} binding also exposed to the body.",
                                            "type": "string"
                                          },
                                          "each": {
                                            "description": "The body node, referenced by ID. Must be an action, javascript or subAgent node declared in workflow.nodes with no other incoming transitions, and must not be an entry point. Its own \"transition\" array is ignored — the forEach node owns what happens after every item finishes. decision nodes are rejected because the execution cache is keyed by node ID, so parallel instances would contend for one cache entry.",
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the node to run once per item.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "collectInto": {
                                            "description": "Variable name receiving the per-item results array. Each entry is {index, item, ok, value?, grounding?, error?, errorName?}, where \"value\" is whatever the body node's own outputVar would have held (undefined when the body declares none) and \"grounding\" is that item's Google Search queries and sources when the body is a grounded INSTRUCTIONS node — the same shape a standalone node exposes as nodes.<id>.grounding. Entries stay aligned with the source array by index, including failed items, so a downstream node can tell \"this item returned nothing\" apart from \"this item was never tried\". Omit only if nothing downstream needs the results.",
                                            "type": "string"
                                          },
                                          "maxConcurrency": {
                                            "description": "How many items run at once. Defaults to 5. Raise carefully: per-item parallelism hits provider rate limits well before it hits platform limits.",
                                            "type": "integer",
                                            "minimum": 1,
                                            "maximum": 20
                                          },
                                          "transition": {
                                            "description": "Transitions to continue the flow after every item has finished.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/checkAgentImport_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ]
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ]
                                            }
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type",
                                          "over",
                                          "as",
                                          "each"
                                        ]
                                      }
                                    ]
                                  }
                                }
                              },
                              "required": [
                                "toolName",
                                "toolDescription",
                                "entryPoints",
                                "nodes"
                              ]
                            },
                            "tools": {
                              "deprecated": true,
                              "description": "Deprecated and ignored. Tool availability is configured by the application, not the agent spec.",
                              "type": "array",
                              "items": {}
                            },
                            "metadata": {
                              "description": "Arbitrary metadata for custom extensions. Not used by the execution engine.",
                              "type": "object",
                              "propertyNames": {
                                "type": "string"
                              },
                              "additionalProperties": {}
                            }
                          },
                          "required": [
                            "version",
                            "name",
                            "prompt",
                            "workflow"
                          ]
                        },
                        "evals": {
                          "default": [],
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string",
                                "minLength": 1
                              },
                              "description": {
                                "anyOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "scheduler": {
                                "anyOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "evalSpec": {},
                              "enabled": {
                                "type": "boolean"
                              },
                              "selfImproveEnabled": {
                                "type": "boolean"
                              },
                              "selfImproveTargetScore": {
                                "anyOf": [
                                  {
                                    "type": "number"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "selfImproveMaxIterations": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991
                              },
                              "folderPath": {
                                "description": "Materialized '/'-separated folder path of the eval (e.g. 'Regressão/Checkout'), or null for root.",
                                "anyOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "tags": {
                                "description": "Free-form labels of the eval.",
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "metadata": {
                                "description": "Free-form data of the eval, including the `sources` conversations it was built from.",
                                "anyOf": [
                                  {
                                    "description": "Free-form data recorded on the eval. Provenance belongs under `sources`, a list whose entries have documented keys so every writer points at the originating conversations the same way. An eval drawn from a single conversation carries a one-element list.",
                                    "type": "object",
                                    "properties": {
                                      "sources": {
                                        "description": "The conversations the eval was built from, most relevant first.",
                                        "maxItems": 25,
                                        "type": "array",
                                        "items": {
                                          "type": "object",
                                          "properties": {
                                            "threadId": {
                                              "description": "Id of the thread the eval was built from.",
                                              "examples": [
                                                "cmc3k5r2b0004l608w1t8fmz9"
                                              ],
                                              "type": "string",
                                              "minLength": 1,
                                              "maxLength": 255
                                            },
                                            "executionId": {
                                              "description": "Id of the agent execution the eval was built from.",
                                              "examples": [
                                                "exec_01j9z3k2b4c5"
                                              ],
                                              "type": "string",
                                              "minLength": 1,
                                              "maxLength": 255
                                            },
                                            "messageId": {
                                              "description": "Id of the specific message the eval was built from.",
                                              "examples": [
                                                "cmc3k9p7f0007"
                                              ],
                                              "type": "string",
                                              "minLength": 1,
                                              "maxLength": 255
                                            },
                                            "url": {
                                              "description": "Link to the source conversation. Must be an absolute http(s) URL.",
                                              "examples": [
                                                "https://platform.docana.com/application/42/agents/a1/logs?search=thread-1"
                                              ],
                                              "type": "string",
                                              "minLength": 1,
                                              "maxLength": 2048
                                            },
                                            "label": {
                                              "description": "Human friendly name of the source conversation.",
                                              "examples": [
                                                "WhatsApp 5511 — 12/08"
                                              ],
                                              "type": "string",
                                              "minLength": 1,
                                              "maxLength": 255
                                            },
                                            "capturedAt": {
                                              "description": "ISO 8601 timestamp of when the eval was captured.",
                                              "examples": [
                                                "2026-08-17T12:00:00.000Z"
                                              ],
                                              "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))$"
                                            }
                                          },
                                          "additionalProperties": {}
                                        }
                                      }
                                    },
                                    "additionalProperties": {}
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              }
                            },
                            "required": [
                              "name",
                              "evalSpec"
                            ]
                          }
                        },
                        "routines": {
                          "default": [],
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string",
                                "minLength": 1
                              },
                              "prompt": {
                                "type": "string"
                              },
                              "enabled": {
                                "default": true,
                                "type": "boolean"
                              },
                              "metadata": {
                                "anyOf": [
                                  {
                                    "type": "object",
                                    "propertyNames": {
                                      "type": "string"
                                    },
                                    "additionalProperties": {}
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "triggers": {
                                "default": [],
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "type": {
                                      "type": "string",
                                      "enum": [
                                        "SCHEDULED",
                                        "API",
                                        "DOCUMENT_EVENT"
                                      ]
                                    },
                                    "enabled": {
                                      "default": true,
                                      "type": "boolean"
                                    },
                                    "cronExpression": {
                                      "anyOf": [
                                        {
                                          "type": "string"
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    },
                                    "collectionIds": {
                                      "default": [],
                                      "type": "array",
                                      "items": {
                                        "type": "integer",
                                        "minimum": -9007199254740991,
                                        "maximum": 9007199254740991
                                      }
                                    },
                                    "eventName": {
                                      "anyOf": [
                                        {
                                          "type": "string"
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    },
                                    "metadata": {
                                      "type": "object",
                                      "propertyNames": {
                                        "type": "string"
                                      },
                                      "additionalProperties": {}
                                    }
                                  },
                                  "required": [
                                    "type"
                                  ]
                                }
                              }
                            },
                            "required": [
                              "name",
                              "prompt"
                            ]
                          }
                        },
                        "insights": {
                          "anyOf": [
                            {
                              "type": "object",
                              "properties": {
                                "enabled": {
                                  "description": "Master kill switch for this agent's insights. When false, no extraction runs anywhere (the post-execution hook is suppressed and the archive API rejects summarize=true) and no prior insights are injected into new conversations.",
                                  "type": "boolean"
                                },
                                "shareWithPastConversations": {
                                  "description": "When true (and `enabled` is true), inject summaries from this user's past archived conversations in the same application into LLM calls that consume conversation history (instruction nodes; decision criteria with EvaluationParams.CONTEXT). Defaults to false.",
                                  "type": "boolean"
                                },
                                "summaryMode": {
                                  "description": "When to extract insights for this agent. \"afterExecution\" (default) runs archive + extraction after every successful agent turn (with or without an End node), so channels like WhatsApp keep producing insights. \"onArchive\" skips the automatic hook; insights are only extracted when the archive API is called with summarize=true.",
                                  "type": "string",
                                  "enum": [
                                    "afterExecution",
                                    "onArchive"
                                  ]
                                },
                                "summaryConfig": {
                                  "description": "Config used when this agent extracts a new summary (End-node generateInsights or archive API with summarize=true).",
                                  "type": "object",
                                  "properties": {
                                    "summaryLength": {
                                      "description": "Target length of the generated summary.",
                                      "type": "string",
                                      "enum": [
                                        "short",
                                        "medium",
                                        "detailed"
                                      ]
                                    },
                                    "customPrompt": {
                                      "description": "Optional extra guidance appended to the summarizer system prompt.",
                                      "type": "string"
                                    },
                                    "historyMessageLimit": {
                                      "description": "Cap on the number of recent messages included when generating the summary. Omitted = no cap.",
                                      "type": "integer",
                                      "exclusiveMinimum": 0,
                                      "maximum": 9007199254740991
                                    },
                                    "maxSummaryChars": {
                                      "description": "Optional cap on the persisted summary length (characters).",
                                      "type": "integer",
                                      "exclusiveMinimum": 0,
                                      "maximum": 9007199254740991
                                    }
                                  }
                                },
                                "frequency": {
                                  "description": "How often insights are extracted. \"onEnd\" (default) extracts once when the conversation is archived. \"everyTurn\" extracts after every message — the legacy behaviour, which costs roughly O(N^2) tokens over an N-turn conversation. When absent, the legacy `summaryMode` is used: \"afterExecution\" maps to \"everyTurn\", anything else maps to \"onEnd\". Any other stored value (e.g. a removed legacy mode) resolves to \"onEnd\", the cheap option.",
                                  "type": "string",
                                  "enum": [
                                    "onEnd",
                                    "everyTurn"
                                  ]
                                },
                                "samplingRate": {
                                  "description": "Share of conversations that produce insights automatically, 0..1. Defaults to 1 (all). The decision is a deterministic hash of (agentId, threadId), so a conversation is either sampled for its whole life or not at all. Explicit archive calls and on-demand generation always run regardless of this rate.",
                                  "type": "number",
                                  "minimum": 0,
                                  "maximum": 1
                                },
                                "dataPoints": {
                                  "description": "Structured data points to extract from the conversation when generating insights.",
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "id": {
                                        "description": "Stable identifier for the data point; reused across saves so snapshot history and aggregations stay correlated over time.",
                                        "type": "string"
                                      },
                                      "name": {
                                        "description": "Human-readable name of the data point (displayed in the UI).",
                                        "type": "string"
                                      },
                                      "description": {
                                        "description": "Instruction describing what this data point should capture from the conversation.",
                                        "type": "string"
                                      },
                                      "type": {
                                        "description": "The expected type of the extracted value.",
                                        "type": "string",
                                        "enum": [
                                          "string",
                                          "number",
                                          "boolean"
                                        ]
                                      }
                                    },
                                    "required": [
                                      "id",
                                      "name",
                                      "description",
                                      "type"
                                    ]
                                  }
                                }
                              },
                              "required": [
                                "enabled"
                              ]
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "evalMockBaseline": {
                          "anyOf": [
                            {
                              "type": "object",
                              "propertyNames": {
                                "type": "string"
                              },
                              "additionalProperties": {
                                "anyOf": [
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "examples": [
                                          "webhook"
                                        ],
                                        "type": "string",
                                        "const": "webhook"
                                      },
                                      "mode": {
                                        "default": "staticResponse",
                                        "type": "string",
                                        "const": "staticResponse"
                                      },
                                      "response": {
                                        "anyOf": [
                                          {
                                            "type": "object",
                                            "properties": {
                                              "status": {
                                                "examples": [
                                                  200
                                                ],
                                                "type": "integer",
                                                "minimum": 100,
                                                "maximum": 599
                                              },
                                              "headers": {
                                                "examples": [
                                                  {
                                                    "content-type": "application/json"
                                                  }
                                                ],
                                                "type": "object",
                                                "propertyNames": {
                                                  "type": "string"
                                                },
                                                "additionalProperties": {
                                                  "type": "string"
                                                }
                                              },
                                              "body": {
                                                "examples": [
                                                  {
                                                    "orderStatus": "shipped"
                                                  }
                                                ],
                                                "$ref": "#/components/schemas/checkAgentImport_schema1"
                                              },
                                              "noResponse": {
                                                "not": {}
                                              }
                                            },
                                            "required": [
                                              "status"
                                            ]
                                          },
                                          {
                                            "type": "object",
                                            "properties": {
                                              "noResponse": {
                                                "examples": [
                                                  true
                                                ],
                                                "type": "boolean",
                                                "const": true
                                              },
                                              "error": {
                                                "examples": [
                                                  "connect ECONNREFUSED 10.0.0.4:443"
                                                ],
                                                "type": "string"
                                              },
                                              "status": {
                                                "not": {}
                                              }
                                            },
                                            "required": [
                                              "noResponse"
                                            ]
                                          }
                                        ]
                                      }
                                    },
                                    "required": [
                                      "type",
                                      "response"
                                    ]
                                  },
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "examples": [
                                          "webhook"
                                        ],
                                        "type": "string",
                                        "const": "webhook"
                                      },
                                      "mode": {
                                        "type": "string",
                                        "const": "sequence"
                                      },
                                      "responses": {
                                        "examples": [
                                          [
                                            {
                                              "status": 400,
                                              "body": {
                                                "error": "CEP inválido"
                                              }
                                            },
                                            {
                                              "status": 201,
                                              "body": {
                                                "data": {
                                                  "status": "AUTORIZADA"
                                                }
                                              }
                                            }
                                          ]
                                        ],
                                        "minItems": 1,
                                        "type": "array",
                                        "items": {
                                          "anyOf": [
                                            {
                                              "type": "object",
                                              "properties": {
                                                "status": {
                                                  "examples": [
                                                    200
                                                  ],
                                                  "type": "integer",
                                                  "minimum": 100,
                                                  "maximum": 599
                                                },
                                                "headers": {
                                                  "examples": [
                                                    {
                                                      "content-type": "application/json"
                                                    }
                                                  ],
                                                  "type": "object",
                                                  "propertyNames": {
                                                    "type": "string"
                                                  },
                                                  "additionalProperties": {
                                                    "type": "string"
                                                  }
                                                },
                                                "body": {
                                                  "examples": [
                                                    {
                                                      "orderStatus": "shipped"
                                                    }
                                                  ],
                                                  "$ref": "#/components/schemas/checkAgentImport_schema1"
                                                },
                                                "noResponse": {
                                                  "not": {}
                                                }
                                              },
                                              "required": [
                                                "status"
                                              ]
                                            },
                                            {
                                              "type": "object",
                                              "properties": {
                                                "noResponse": {
                                                  "examples": [
                                                    true
                                                  ],
                                                  "type": "boolean",
                                                  "const": true
                                                },
                                                "error": {
                                                  "examples": [
                                                    "connect ECONNREFUSED 10.0.0.4:443"
                                                  ],
                                                  "type": "string"
                                                },
                                                "status": {
                                                  "not": {}
                                                }
                                              },
                                              "required": [
                                                "noResponse"
                                              ]
                                            }
                                          ]
                                        }
                                      }
                                    },
                                    "required": [
                                      "type",
                                      "mode",
                                      "responses"
                                    ]
                                  }
                                ]
                              }
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "spec"
                      ]
                    }
                  },
                  "applicationId": {
                    "description": "Target application id.",
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  }
                },
                "required": [
                  "exportVersion",
                  "agent"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Existence report for the bundle agents",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "exists": {
                      "description": "Whether the bundle's root agent already exists in the target application.",
                      "type": "boolean"
                    },
                    "rootAgent": {
                      "description": "The agent in the target application that matches the bundle root, or null when none exists.",
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "id": {
                              "description": "Id of the existing agent.",
                              "examples": [
                                "cmc4v8xq10001l708h2vxk9d3"
                              ],
                              "type": "string"
                            },
                            "name": {
                              "description": "Name of the existing agent. Null when the agent has no name.",
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            }
                          },
                          "required": [
                            "id",
                            "name"
                          ],
                          "additionalProperties": {}
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "subAgentsExist": {
                      "description": "Whether at least one of the bundle's sub-agents already exists.",
                      "type": "boolean"
                    },
                    "existingSubAgents": {
                      "description": "The bundle sub-agents that already exist in the target application.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "Id of the existing sub-agent.",
                            "examples": [
                              "cmc4v9dr20002l708j5tze8b4"
                            ],
                            "type": "string"
                          },
                          "name": {
                            "description": "Name of the existing sub-agent. Null when the agent has no name.",
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "name"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "exists",
                    "rootAgent",
                    "subAgentsExist",
                    "existingSubAgents"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid payload or missing applicationId",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Check failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/schema/": {
      "get": {
        "operationId": "getAgentSpecJsonSchema",
        "summary": "Get the AgentSpec V2 JSON Schema",
        "tags": [
          "agents"
        ],
        "description": "Returns the JSON Schema (draft 2020-12) of the agent spec, derived from the canonical zod definition. Served as `application/schema+json` with a public cache policy.",
        "responses": {
          "200": {
            "description": "The AgentSpec V2 JSON Schema document"
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/schema/validate/": {
      "post": {
        "operationId": "validateAgentSpec",
        "summary": "Validate an agent spec",
        "tags": [
          "agents"
        ],
        "description": "Validates an agent spec against the AgentSpec V2 JSON Schema (see `GET /api/v1/agents/schema/`) without persisting anything. After a clean validation, create one draft with `createAgent`. Accepts either `{ \"spec\": <agent-spec> }` or the spec object at the top level.",
        "requestBody": {
          "required": true,
          "description": "The agent spec wrapped in a `spec` field. The bare spec object is also accepted at the top level.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "spec": {
                    "description": "The agent spec to validate against the AgentSpecV2 schema.",
                    "type": "object",
                    "properties": {
                      "version": {
                        "description": "Schema version. Must be \"2.0\".",
                        "type": "string",
                        "const": "2.0"
                      },
                      "id": {
                        "description": "Unique identifier for this agent. Auto-generated if not provided.",
                        "type": "string"
                      },
                      "name": {
                        "description": "Human-readable name of the agent.",
                        "type": "string"
                      },
                      "prompt": {
                        "description": "System instructions for the agent. Can be a single string or an array of strings joined at runtime.",
                        "anyOf": [
                          {
                            "type": "string",
                            "minLength": 1
                          },
                          {
                            "minItems": 1,
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1
                            }
                          }
                        ]
                      },
                      "llm": {
                        "description": "LLM configuration for the router persona. Optional; uses platform defaults when omitted.",
                        "type": "object",
                        "properties": {
                          "provider": {
                            "description": "The LLM provider identifier (e.g., \"google\", \"openai\").",
                            "type": "string"
                          },
                          "model": {
                            "description": "The model name to use (e.g., \"gemini-2.0-flash\").",
                            "type": "string"
                          },
                          "temperature": {
                            "description": "Sampling temperature (0-2). IGNORED on Gemini 3.x models, which Google deprecated this parameter for on 2026-07-21 — it is accepted and silently discarded, so it no longer makes output more deterministic. Still accepted for older models and for backwards compatibility with existing specs.",
                            "type": "number"
                          },
                          "maxOutputTokens": {
                            "description": "Maximum number of tokens the model can generate.",
                            "type": "number"
                          },
                          "toolChoice": {
                            "description": "Controls how the model uses tools: auto (model decides), required (must use a tool), none (no tools).",
                            "type": "string",
                            "enum": [
                              "auto",
                              "required",
                              "none"
                            ]
                          },
                          "jsonMode": {
                            "description": "If true, the model outputs valid JSON.",
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "provider",
                          "model"
                        ]
                      },
                      "inlineEvaluationCriteria": {
                        "description": "Map of criteria ID to its full definition. Decision nodes reference these by key. These are criteria that have not been persisted to the database yet. During sandbox execution, they are loaded into memory. During publish, they are persisted to the database and this field is cleared.",
                        "type": "object",
                        "propertyNames": {
                          "type": "string"
                        },
                        "additionalProperties": {
                          "type": "object",
                          "properties": {
                            "name": {
                              "description": "Human-readable name of this evaluation criteria. MUST be a non-empty short noun phrase (e.g. \"Real-Estate Availability Intent\"). Empty strings are forbidden.",
                              "type": "string"
                            },
                            "type": {
                              "description": "The evaluation criteria type (e.g., CUSTOM, QUALITY_HELPFULNESS).",
                              "type": "string",
                              "enum": [
                                "QUALITY_ENGAGINGNESS",
                                "QUALITY_COHERENCE",
                                "QUALITY_CONSISTENCY",
                                "QUALITY_FLUENCY",
                                "QUALITY_RELEVANCE",
                                "SECURITY_FINANCIAL_DETECTION",
                                "SECURITY_PII_DETECTION",
                                "SECURITY_ANOMALOUS_CONVERSATION",
                                "PERSONALITY_EXTRAVERSION",
                                "PERSONALITY_OPEN_TO_EXPERIENCE",
                                "PERSONALITY_CONSCIENTIOUSNESS",
                                "PERSONALITY_AGREEABLENESS",
                                "PERSONALITY_NEUROTICISM",
                                "PERSONALITY_OTHER",
                                "DOCUMENT_INSIGHTS",
                                "CUSTOM"
                              ]
                            },
                            "evaluationCriteria": {
                              "description": "REQUIRED non-empty instruction the evaluator follows to assess the input. One or two sentences in plain language: what to assess, and (if structuredDataParams is set) how to populate each declared field. Example: \"Decide whether the user is asking about real-estate availability. Set isAvailability to true only when the user is clearly asking whether a property is available; otherwise false.\" Empty strings, null, or omission make the reasoning useless and are forbidden.",
                              "type": "string"
                            },
                            "evaluationSteps": {
                              "description": "Ordered evaluation steps for the criteria.",
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "evaluationParams": {
                              "description": "Parameters used during evaluation (e.g., INPUT, CONTEXT).",
                              "type": "array",
                              "items": {
                                "type": "string",
                                "enum": [
                                  "INPUT",
                                  "ACTUAL_OUTPUT",
                                  "EXPECTED_OUTPUT",
                                  "CONTEXT",
                                  "RETRIEVAL_CONTEXT",
                                  "EXECUTION_CONTEXT"
                                ]
                              }
                            },
                            "structuredDataParams": {
                              "description": "Map of field name to a natural-language description of what to extract. The description should encode both the type and the legal values, e.g. \"true if the user is asking about real-estate availability, false otherwise\" (boolean), \"one of: AVAILABILITY, PRICING, CONTACT, OTHER\" (enum), or \"numeric score 1-5 reflecting urgency\" (number). Each declared field becomes a routing key accessible from transition conditions as \"evaluation.structuredData.<field>\" (and is also flattened into top-level vars for action templates). Prefer this for routing on what the user meant or asked; use scores.mean for confidence/quality routing.",
                              "anyOf": [
                                {
                                  "type": "object",
                                  "propertyNames": {
                                    "type": "string"
                                  },
                                  "additionalProperties": {}
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "metadata": {
                              "description": "Additional metadata for the criteria.",
                              "anyOf": [
                                {
                                  "type": "object",
                                  "propertyNames": {
                                    "type": "string"
                                  },
                                  "additionalProperties": {}
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "enabled": {
                              "description": "Whether this criteria is enabled. Defaults to true.",
                              "type": "boolean"
                            }
                          },
                          "required": [
                            "name",
                            "type",
                            "evaluationCriteria"
                          ]
                        }
                      },
                      "workflow": {
                        "description": "The workflow definition including entry points and execution nodes.",
                        "type": "object",
                        "properties": {
                          "toolName": {
                            "description": "The tool name used to invoke this agent in the workflow.",
                            "type": "string"
                          },
                          "toolDescription": {
                            "description": "A description of what this agent does, shown to the LLM router.",
                            "type": "string"
                          },
                          "executionTimeoutSeconds": {
                            "description": "Wall-clock ceiling for ONE execution of this workflow, in seconds (30-1800). When the deadline passes the run is aborted — in-flight model calls are cancelled, sub-agents included — and the execution finishes with status TIMED_OUT, with the reason recorded on the nodes that were cut. Optional: an agent that declares nothing keeps the platform behavior (no explicit ceiling). Declare it when the agent legitimately runs for minutes (deep research, long tool chains) so a slow run is never mistaken for a hung one, or when it must never occupy a worker past a known bound. The budget is per attempt: a run resumed after a crash starts a fresh timer.",
                            "type": "integer",
                            "minimum": 30,
                            "maximum": 1800
                          },
                          "entryPoints": {
                            "description": "Entry points into the workflow. MUST contain at least one node ID; an empty array makes the workflow non-executable. When you restructure or rename the first node, update this list in the same operation so it points at the new entry node.",
                            "minItems": 1,
                            "type": "array",
                            "items": {
                              "anyOf": [
                                {
                                  "description": "Node ID to use as an unconditional entry point.",
                                  "type": "string"
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "nodeId": {
                                      "description": "The ID of the entry point node.",
                                      "type": "string"
                                    },
                                    "if": {
                                      "description": "Optional condition that must be met for this entry point to activate.",
                                      "$ref": "#/components/schemas/validateAgentSpec_schema0"
                                    }
                                  },
                                  "required": [
                                    "nodeId"
                                  ]
                                }
                              ]
                            }
                          },
                          "nodes": {
                            "description": "The workflow nodes: decision, action, subAgent, end, state, hub, jump, clearCache, javascript, or forEach.",
                            "type": "array",
                            "items": {
                              "anyOf": [
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "decision"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this decision node.",
                                      "type": "string"
                                    },
                                    "evaluationCriteria": {
                                      "description": "Evaluation criteria IDs (string references) or inline criteria objects.",
                                      "type": "array",
                                      "items": {
                                        "anyOf": [
                                          {
                                            "type": "string"
                                          },
                                          {
                                            "type": "object",
                                            "properties": {
                                              "id": {
                                                "type": "string"
                                              },
                                              "name": {
                                                "description": "Required non-empty short human-readable name for this criterion (e.g. \"Real-Estate Availability Intent\"). Never an empty string.",
                                                "type": "string"
                                              },
                                              "type": {
                                                "type": "string",
                                                "enum": [
                                                  "QUALITY_ENGAGINGNESS",
                                                  "QUALITY_COHERENCE",
                                                  "QUALITY_CONSISTENCY",
                                                  "QUALITY_FLUENCY",
                                                  "QUALITY_RELEVANCE",
                                                  "SECURITY_FINANCIAL_DETECTION",
                                                  "SECURITY_PII_DETECTION",
                                                  "SECURITY_ANOMALOUS_CONVERSATION",
                                                  "PERSONALITY_EXTRAVERSION",
                                                  "PERSONALITY_OPEN_TO_EXPERIENCE",
                                                  "PERSONALITY_CONSCIENTIOUSNESS",
                                                  "PERSONALITY_AGREEABLENESS",
                                                  "PERSONALITY_NEUROTICISM",
                                                  "PERSONALITY_OTHER",
                                                  "DOCUMENT_INSIGHTS",
                                                  "CUSTOM"
                                                ]
                                              },
                                              "evaluationCriteria": {
                                                "description": "REQUIRED non-empty instruction telling the evaluator what to assess. One or two sentences in plain language: what to evaluate, and — when structuredDataParams is set — how to populate each declared field. Empty strings, null, or omission are forbidden; an empty description leaves the reasoning useless. Example: \"Decide whether the user is asking about real-estate availability. Set isAvailability to true only when the user is clearly asking whether a property is available; otherwise false.\"",
                                                "type": "string"
                                              },
                                              "evaluationSteps": {
                                                "type": "array",
                                                "items": {
                                                  "type": "string"
                                                }
                                              },
                                              "structuredDataParams": {
                                                "anyOf": [
                                                  {
                                                    "type": "object",
                                                    "propertyNames": {
                                                      "type": "string"
                                                    },
                                                    "additionalProperties": {}
                                                  },
                                                  {
                                                    "type": "null"
                                                  }
                                                ]
                                              },
                                              "metadata": {
                                                "anyOf": [
                                                  {
                                                    "type": "object",
                                                    "propertyNames": {
                                                      "type": "string"
                                                    },
                                                    "additionalProperties": {}
                                                  },
                                                  {
                                                    "type": "null"
                                                  }
                                                ]
                                              },
                                              "enabled": {
                                                "type": "boolean"
                                              },
                                              "applicationId": {
                                                "type": "number"
                                              },
                                              "evaluationParams": {
                                                "type": "array",
                                                "items": {
                                                  "type": "string",
                                                  "enum": [
                                                    "INPUT",
                                                    "ACTUAL_OUTPUT",
                                                    "EXPECTED_OUTPUT",
                                                    "CONTEXT",
                                                    "RETRIEVAL_CONTEXT",
                                                    "EXECUTION_CONTEXT"
                                                  ]
                                                }
                                              }
                                            },
                                            "required": [
                                              "name",
                                              "type",
                                              "evaluationCriteria"
                                            ]
                                          }
                                        ]
                                      }
                                    },
                                    "transition": {
                                      "description": "Transitions to other nodes based on evaluation results.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/validateAgentSpec_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    },
                                    "cachePolicy": {
                                      "description": "Controls execution caching for this decision node across messages in a conversation. auto (default): cache result and use a lightweight guard evaluation to detect staleness. always: always use cached result until explicitly cleared. never: always re-evaluate all criteria every message (disables caching).",
                                      "type": "string",
                                      "enum": [
                                        "auto",
                                        "always",
                                        "never"
                                      ]
                                    },
                                    "selectionPolicy": {
                                      "description": "Controls which enabled criteria are evaluated each message. all (default): every enabled criterion runs. contextual: a lightweight router selects only the criteria relevant to the current input and conversation state; the rest are skipped. Skipped criteria are not evaluated, so their structuredData fields are absent downstream (route on them with the \"exists\"/\"notExists\" operators) and scores.mean reflects only the criteria that ran.",
                                      "type": "string",
                                      "enum": [
                                        "all",
                                        "contextual"
                                      ]
                                    },
                                    "alwaysRunCriteria": {
                                      "description": "Only used when selectionPolicy is \"contextual\": IDs of evaluation criteria that always run (they bypass the router); every other criterion is AI-selected per message. Use this to pin extractors whose structuredData a downstream node depends on. Ignored when selectionPolicy is \"all\".",
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    },
                                    "contextualSelectionPrompt": {
                                      "description": "Only used when selectionPolicy is \"contextual\": extra author guidance appended to the built-in router prompt to steer which criteria it picks (e.g. \"prefer running Consultar NFSe whenever the user mentions a nota fiscal, even indirectly\"). It augments the router — it does not replace its output contract or the safe fallback of running everything. Ignored when selectionPolicy is \"all\".",
                                      "type": "string"
                                    },
                                    "routingPolicy": {
                                      "description": "How many REASONINGS (criteria) may win the routing on this node per message. all (default): every matching conditional transition fires in parallel. bestReasoning: only the highest-scoring reasoning wins — ALL matched transitions whose condition is anchored on it fire (they are that reasoning's flow), everything anchored on other reasonings is suppressed. topReasonings: like bestReasoning but the best `maxReasonings` reasonings win. A matched transition is anchored on the highest-scoring criterion its condition references (via \"resultsById.<id>.score\" paths, at any nesting). Score ties between reasonings break by position in this node's evaluationCriteria list (earlier wins) — reorder the list to set priority. Matched transitions that reference NO criterion score (pure structuredData/context/state conditions) are outside the competition and always fire, like \"default\" and unconditional transitions. Criteria evaluation is unaffected — this arbitrates AFTER scoring, so it is the reliable way to get \"only one reasoning wins\" (independent per-criterion evaluations cannot be prompted into exclusivity).",
                                      "type": "string",
                                      "enum": [
                                        "all",
                                        "bestReasoning",
                                        "topReasonings"
                                      ]
                                    },
                                    "maxReasonings": {
                                      "description": "Only used when routingPolicy is \"topReasonings\": how many of the highest-scoring reasonings win the routing. Ignored for other policies (\"bestReasoning\" is exactly maxReasonings = 1).",
                                      "type": "integer",
                                      "minimum": 1,
                                      "maximum": 9007199254740991
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type",
                                    "evaluationCriteria",
                                    "transition"
                                  ]
                                },
                                {
                                  "oneOf": [
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "action"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this action node.",
                                          "type": "string"
                                        },
                                        "mode": {
                                          "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                          "type": "string",
                                          "enum": [
                                            "sync",
                                            "async"
                                          ]
                                        },
                                        "outputVar": {
                                          "description": "Variable name to store the action output for use by downstream nodes.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Transitions to other nodes after this action completes.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/validateAgentSpec_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        },
                                        "actionType": {
                                          "type": "string",
                                          "const": "INSTRUCTIONS"
                                        },
                                        "config": {
                                          "type": "object",
                                          "properties": {
                                            "instructions": {
                                              "description": "The instructions for the LLM to execute.",
                                              "type": "string"
                                            },
                                            "modelTier": {
                                              "description": "The model tier to use for this instruction. Defaults to regular.",
                                              "type": "string",
                                              "enum": [
                                                "lite",
                                                "regular",
                                                "pro"
                                              ]
                                            },
                                            "thinkingEffortPct": {
                                              "description": "Thinking effort percentage (0-100) controlling how much reasoning the model applies.",
                                              "type": "number",
                                              "minimum": 0,
                                              "maximum": 100
                                            },
                                            "maxOutputTokens": {
                                              "description": "Maximum tokens the model may generate for this node. On thinking models the budget is SHARED between reasoning and output — reasoning routinely consumes most of it — so a node whose structured output is truncated is usually better served by lowering thinkingEffortPct than by raising this. Defaults to the model maximum when omitted.",
                                              "type": "integer",
                                              "minimum": 1,
                                              "maximum": 9007199254740991
                                            },
                                            "maxRetries": {
                                              "description": "How many times this node retries a failed model call. Defaults to 2 when the node has an outputSchema and 5 otherwise. Raise it for nodes whose long outputs are exposed to dropped provider streams; it does not help failures the model reproduces deterministically.",
                                              "type": "integer",
                                              "minimum": 1,
                                              "maximum": 10
                                            },
                                            "toolChoiceMode": {
                                              "description": "Tool selection mode for this instruction. Defaults to auto when omitted.",
                                              "type": "string",
                                              "enum": [
                                                "auto",
                                                "none",
                                                "tool",
                                                "tools"
                                              ]
                                            },
                                            "toolChoiceToolName": {
                                              "description": "When toolChoiceMode is \"tool\", the specific tool name to force.",
                                              "type": "string"
                                            },
                                            "toolChoiceToolNames": {
                                              "description": "When toolChoiceMode is \"tools\", the list of allowed tool names.",
                                              "type": "array",
                                              "items": {
                                                "type": "string"
                                              }
                                            },
                                            "suppressTextResponse": {
                                              "description": "When true, text output from the LLM is suppressed and only tool-call results are emitted. Useful when the instruction should only invoke tools (e.g., displayMedia) without generating follow-up text.",
                                              "type": "boolean"
                                            },
                                            "stopAfterFirstToolCall": {
                                              "description": "When true and a single tool is forced with text suppressed, the instruction stops after the first successful tool call. Defaults to false, which allows the tool to be called across multiple steps.",
                                              "type": "boolean"
                                            },
                                            "internal": {
                                              "description": "When true, this node is an intermediate step: its text/structured output is NOT shown to the user (not streamed, not persisted as a visible message part) and is only captured into the node's outputVar for downstream nodes. Reasoning and tool-call activity chips remain visible. Use for internal hand-offs (e.g. tool-driven data synthesis a later node consumes); the user-facing reply should come from a later, non-internal node.",
                                              "type": "boolean"
                                            },
                                            "outputSchema": {
                                              "description": "JSON Schema for structured output. When provided, the LLM will output valid JSON matching this schema instead of free-form text.",
                                              "type": "object",
                                              "properties": {
                                                "type": {
                                                  "description": "JSON Schema type, must be \"object\" for structured output.",
                                                  "type": "string",
                                                  "const": "object"
                                                },
                                                "properties": {
                                                  "description": "Schema properties defining the expected output structure.",
                                                  "type": "object",
                                                  "propertyNames": {
                                                    "type": "string"
                                                  },
                                                  "additionalProperties": {}
                                                },
                                                "required": {
                                                  "description": "Array of required property names.",
                                                  "type": "array",
                                                  "items": {
                                                    "type": "string"
                                                  }
                                                },
                                                "additionalProperties": {
                                                  "description": "Whether to allow additional properties not defined in the schema.",
                                                  "type": "boolean"
                                                },
                                                "description": {
                                                  "description": "Description of the expected output to guide the LLM.",
                                                  "type": "string"
                                                }
                                              },
                                              "required": [
                                                "type",
                                                "properties"
                                              ]
                                            },
                                            "grounding": {
                                              "description": "Model-side grounding for this node. Only Google Search is available today.",
                                              "type": "object",
                                              "properties": {
                                                "googleSearch": {
                                                  "description": "Enable Google Search grounding: the model searches the public web (via Gemini's built-in google_search tool) while executing this instruction and answers from what it finds. Set `{}` to enable with defaults. The node result then carries `grounding` — the queries Google ran and the sources it cited, each with the resolved article URL, its domain and the passages of the reply it supports — readable downstream as `nodes.<nodeId>.grounding` in javascript nodes and templates; the text/JSON reply itself still flows through outputVar as usual. With an outputSchema the search runs first and the JSON is synthesized afterwards with the numbered source list, so declare a `sourceIds` or `url` field if you want citations inside the structured output. Incompatible with toolChoiceMode \"tool\" and with suppressTextResponse (a forced tool call and Google Search in one request returns an empty reply); with toolChoiceMode \"none\" the node still searches but calls no other tool. Each prompt costs Google one search query per query the model decides to run (usually 4–10), billed per query beyond the project's free tier.",
                                                  "type": "object",
                                                  "properties": {
                                                    "excludeDomains": {
                                                      "description": "Domains Google Search must not ground on, e.g. [\"youtube.com\", \"reddit.com\"]. A domain excludes its subdomains too.",
                                                      "type": "array",
                                                      "items": {
                                                        "type": "string"
                                                      }
                                                    }
                                                  }
                                                }
                                              }
                                            },
                                            "urlContext": {
                                              "description": "Gemini URL context: hand the model a list of URLs to READ IN FULL server-side instead of fetching their text into a variable first. The URLs come from the fixed \"urls\" list, from the \"from\" value path, or from both (fixed first). They are appended to the end of the instruction and the provider fetches and reads the pages inside the same call. With an outputSchema the node runs as a SINGLE call (reading and synthesis must share it), so pair it with toolChoiceMode \"none\" unless the node truly needs function tools. Limits: 20 URLs per call (extra ones are dropped and reported as `truncated`), public pages only — paywalls, Google News redirect links and private hosts fail. The model may skip fetching when the URLs sit inside a very long prompt, so prefer a dedicated short reading node over bolting URLs onto a large synthesis prompt. The node output carries `urlContext.{requested,retrieved,unread,truncated,invalid,unresolved,supported,tokens}`. `unread` is the integrity signal — it lists every URL the model did not read, including the ones dropped by the 20-URL cap — so branch on `nodes.<id>.urlContext.unread` for a fallback reader (inside a forEach body it holds only the last item). `unresolved` says the \"from\" path resolved to nothing, `invalid` lists entries that were not http(s) URLs, and `supported` is false when the model could not carry the tool: in those cases nothing was read at all. Retrieved page content is billed as input tokens and added to the node usage as `urlContextTokens`. Gemini 3+ models only.",
                                              "type": "object",
                                              "properties": {
                                                "urls": {
                                                  "description": "Fixed http(s) URLs to read on every run, written out here — for pages that do not change per execution (a status page, a policy, a price list). Combine with \"from\" to read a fixed set plus whatever the run produced; the two lists concatenate, fixed URLs first.",
                                                  "type": "array",
                                                  "items": {
                                                    "type": "string"
                                                  }
                                                },
                                                "from": {
                                                  "description": "Dotted VALUE PATH (same resolution as forEach \"over\": workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — e.g. \"paraLer.soUrls\" or \"nodes.pick.result.urls\") to a URL list the run produced: an array of http(s) URL strings, a single URL string, or a JSON-encoded array string. Not a Handlebars template; a path wrapped in {{ }} is accepted and unwrapped.",
                                                  "type": "string",
                                                  "minLength": 1
                                                }
                                              }
                                            }
                                          },
                                          "required": [
                                            "instructions"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "mode",
                                        "transition",
                                        "actionType",
                                        "config"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "action"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this action node.",
                                          "type": "string"
                                        },
                                        "mode": {
                                          "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                          "type": "string",
                                          "enum": [
                                            "sync",
                                            "async"
                                          ]
                                        },
                                        "outputVar": {
                                          "description": "Variable name to store the action output for use by downstream nodes.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Transitions to other nodes after this action completes.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/validateAgentSpec_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        },
                                        "actionType": {
                                          "type": "string",
                                          "const": "EMAIL"
                                        },
                                        "config": {
                                          "type": "object",
                                          "properties": {
                                            "to": {
                                              "type": "string"
                                            },
                                            "senderType": {
                                              "type": "string",
                                              "enum": [
                                                "default",
                                                "gmail"
                                              ]
                                            },
                                            "gmailIntegrationId": {
                                              "type": "string"
                                            },
                                            "subject": {
                                              "type": "string"
                                            },
                                            "body": {
                                              "type": "string"
                                            },
                                            "cc": {
                                              "type": "string"
                                            },
                                            "bcc": {
                                              "type": "string"
                                            },
                                            "attachments": {
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "documentId": {
                                                    "type": "number"
                                                  },
                                                  "url": {
                                                    "type": "string"
                                                  },
                                                  "filename": {
                                                    "type": "string"
                                                  }
                                                }
                                              }
                                            },
                                            "templateId": {
                                              "type": "string"
                                            },
                                            "templateName": {
                                              "type": "string"
                                            },
                                            "applicationId": {
                                              "type": "number"
                                            }
                                          },
                                          "required": [
                                            "to",
                                            "subject",
                                            "body"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "mode",
                                        "transition",
                                        "actionType",
                                        "config"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "action"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this action node.",
                                          "type": "string"
                                        },
                                        "mode": {
                                          "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                          "type": "string",
                                          "enum": [
                                            "sync",
                                            "async"
                                          ]
                                        },
                                        "outputVar": {
                                          "description": "Variable name to store the action output for use by downstream nodes.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Transitions to other nodes after this action completes.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/validateAgentSpec_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        },
                                        "actionType": {
                                          "type": "string",
                                          "const": "WEBHOOK"
                                        },
                                        "config": {
                                          "type": "object",
                                          "properties": {
                                            "url": {
                                              "type": "string"
                                            },
                                            "method": {
                                              "type": "string",
                                              "enum": [
                                                "GET",
                                                "POST",
                                                "PUT",
                                                "PATCH",
                                                "DELETE"
                                              ]
                                            },
                                            "headers": {
                                              "type": "object",
                                              "propertyNames": {
                                                "type": "string"
                                              },
                                              "additionalProperties": {
                                                "type": "string"
                                              }
                                            },
                                            "queryParams": {
                                              "type": "object",
                                              "propertyNames": {
                                                "type": "string"
                                              },
                                              "additionalProperties": {
                                                "type": "string"
                                              }
                                            },
                                            "body": {
                                              "type": "string"
                                            },
                                            "timeout": {
                                              "type": "number"
                                            },
                                            "responseMode": {
                                              "description": "How to decode the response body. \"json\" (default): parse as JSON/text and expose via varsDelta. \"attachment\": read as binary bytes for multimodal input (e.g. PDFs, images).",
                                              "type": "string",
                                              "enum": [
                                                "json",
                                                "attachment"
                                              ]
                                            },
                                            "asMessage": {
                                              "description": "When true, append the response to the conversation as a new user message so downstream LLM nodes see it. In \"attachment\" mode the message carries a file content part; in \"json\" mode it carries the stringified body as text. Defaults to false — preserving the historical behavior where webhook responses only flow through varsDelta.",
                                              "type": "boolean"
                                            },
                                            "suppressNoResponseFallback": {
                                              "description": "Marks the webhook as a fire-and-forget trigger: the conversation is meant to end here, with the rest happening on the receiving system. When the call succeeds and the turn finishes without sending anything to the user, the channel skips its automatic \"sorry, something went wrong\" fallback message. A failed call (HTTP >= 400) still gets the fallback, since the user is then left waiting for nothing.",
                                              "type": "boolean"
                                            }
                                          },
                                          "required": [
                                            "url",
                                            "method"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "mode",
                                        "transition",
                                        "actionType",
                                        "config"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "action"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this action node.",
                                          "type": "string"
                                        },
                                        "mode": {
                                          "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                          "type": "string",
                                          "enum": [
                                            "sync",
                                            "async"
                                          ]
                                        },
                                        "outputVar": {
                                          "description": "Variable name to store the action output for use by downstream nodes.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Transitions to other nodes after this action completes.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/validateAgentSpec_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        },
                                        "actionType": {
                                          "type": "string",
                                          "const": "DOCUMENT_TEMPLATE"
                                        },
                                        "config": {
                                          "type": "object",
                                          "properties": {
                                            "templateId": {
                                              "type": "string"
                                            },
                                            "templateName": {
                                              "type": "string"
                                            },
                                            "sendEmail": {
                                              "type": "boolean"
                                            },
                                            "sendWhatsApp": {
                                              "type": "boolean"
                                            },
                                            "recipientEmail": {
                                              "type": "string"
                                            }
                                          },
                                          "required": [
                                            "templateId"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "mode",
                                        "transition",
                                        "actionType",
                                        "config"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "action"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this action node.",
                                          "type": "string"
                                        },
                                        "mode": {
                                          "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                          "type": "string",
                                          "enum": [
                                            "sync",
                                            "async"
                                          ]
                                        },
                                        "outputVar": {
                                          "description": "Variable name to store the action output for use by downstream nodes.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Transitions to other nodes after this action completes.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/validateAgentSpec_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        },
                                        "actionType": {
                                          "type": "string",
                                          "const": "TOOL_CALL"
                                        },
                                        "config": {
                                          "type": "object",
                                          "properties": {
                                            "toolName": {
                                              "description": "The name of the common tool to invoke.",
                                              "type": "string"
                                            },
                                            "parameters": {
                                              "description": "Per-parameter configuration. Keys are parameter names from the tool schema.",
                                              "type": "object",
                                              "propertyNames": {
                                                "type": "string"
                                              },
                                              "additionalProperties": {
                                                "type": "object",
                                                "properties": {
                                                  "mode": {
                                                    "description": "Whether this parameter is hardcoded (static) or filled by the LLM at runtime (dynamic).",
                                                    "type": "string",
                                                    "enum": [
                                                      "static",
                                                      "dynamic"
                                                    ]
                                                  },
                                                  "staticValue": {
                                                    "description": "The fixed value for this parameter. Required when mode is \"static\"."
                                                  },
                                                  "instructions": {
                                                    "description": "Optional guidance for the LLM when filling this parameter (only used when mode is \"dynamic\").",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "mode"
                                                ]
                                              }
                                            },
                                            "instructions": {
                                              "description": "General instructions for the LLM when resolving dynamic parameters.",
                                              "type": "string"
                                            },
                                            "skipKnowledgeSearch": {
                                              "description": "When a node has dynamic parameters, the model is normally forced to call similaritySearch first so parameter values are grounded in the knowledge base, costing one extra model round. Set true for tools that need no knowledge context (for example code execution) to call the configured tool directly. Ignored when every parameter is static, since no model runs at all.",
                                              "type": "boolean"
                                            }
                                          },
                                          "required": [
                                            "toolName"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "mode",
                                        "transition",
                                        "actionType",
                                        "config"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "action"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this action node.",
                                          "type": "string"
                                        },
                                        "mode": {
                                          "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                          "type": "string",
                                          "enum": [
                                            "sync",
                                            "async"
                                          ]
                                        },
                                        "outputVar": {
                                          "description": "Variable name to store the action output for use by downstream nodes.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Transitions to other nodes after this action completes.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/validateAgentSpec_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        },
                                        "actionType": {
                                          "type": "string",
                                          "const": "FOLLOW_UP"
                                        },
                                        "config": {
                                          "type": "object",
                                          "properties": {
                                            "delayMinutes": {
                                              "description": "Minutes to wait before checking whether to run the inner action. Common presets: 5, 10, 15. Maximum 1440 (24h). Cloud Scheduler is cron-based so the actual fire time is rounded to the next minute boundary.",
                                              "type": "integer",
                                              "minimum": 1,
                                              "maximum": 1440
                                            },
                                            "cancelOnUserMessage": {
                                              "description": "When true (default), skip the inner action if any USER message arrived after the node was reached. Set to false only if the follow-up should fire even after the user has replied.",
                                              "type": "boolean"
                                            },
                                            "cancelOnAssistantMessage": {
                                              "description": "When true (default), skip the inner action if any ASSISTANT text message was sent after the node was reached. Tool-only assistant messages (no text content) do NOT count. Prevents double-pinging when another node already produced a response.",
                                              "type": "boolean"
                                            },
                                            "cancelOnArchive": {
                                              "description": "When true (default), skip the inner action if the thread was archived between scheduling and firing.",
                                              "type": "boolean"
                                            },
                                            "action": {
                                              "description": "The inner action to run when the delay elapses and cancel rules pass. INSTRUCTIONS produces an LLM-generated text message (good for \"Are you still there?\"-style nudges). TOOL_CALL fires a display tool (good for offering options or showing media).",
                                              "oneOf": [
                                                {
                                                  "type": "object",
                                                  "properties": {
                                                    "actionType": {
                                                      "type": "string",
                                                      "const": "INSTRUCTIONS"
                                                    },
                                                    "config": {
                                                      "type": "object",
                                                      "properties": {
                                                        "instructions": {
                                                          "description": "The instructions for the LLM to execute.",
                                                          "type": "string"
                                                        },
                                                        "modelTier": {
                                                          "description": "The model tier to use for this instruction. Defaults to regular.",
                                                          "type": "string",
                                                          "enum": [
                                                            "lite",
                                                            "regular",
                                                            "pro"
                                                          ]
                                                        },
                                                        "thinkingEffortPct": {
                                                          "description": "Thinking effort percentage (0-100) controlling how much reasoning the model applies.",
                                                          "type": "number",
                                                          "minimum": 0,
                                                          "maximum": 100
                                                        },
                                                        "maxOutputTokens": {
                                                          "description": "Maximum tokens the model may generate for this node. On thinking models the budget is SHARED between reasoning and output — reasoning routinely consumes most of it — so a node whose structured output is truncated is usually better served by lowering thinkingEffortPct than by raising this. Defaults to the model maximum when omitted.",
                                                          "type": "integer",
                                                          "minimum": 1,
                                                          "maximum": 9007199254740991
                                                        },
                                                        "maxRetries": {
                                                          "description": "How many times this node retries a failed model call. Defaults to 2 when the node has an outputSchema and 5 otherwise. Raise it for nodes whose long outputs are exposed to dropped provider streams; it does not help failures the model reproduces deterministically.",
                                                          "type": "integer",
                                                          "minimum": 1,
                                                          "maximum": 10
                                                        },
                                                        "toolChoiceMode": {
                                                          "description": "Tool selection mode for this instruction. Defaults to auto when omitted.",
                                                          "type": "string",
                                                          "enum": [
                                                            "auto",
                                                            "none",
                                                            "tool",
                                                            "tools"
                                                          ]
                                                        },
                                                        "toolChoiceToolName": {
                                                          "description": "When toolChoiceMode is \"tool\", the specific tool name to force.",
                                                          "type": "string"
                                                        },
                                                        "toolChoiceToolNames": {
                                                          "description": "When toolChoiceMode is \"tools\", the list of allowed tool names.",
                                                          "type": "array",
                                                          "items": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "suppressTextResponse": {
                                                          "description": "When true, text output from the LLM is suppressed and only tool-call results are emitted. Useful when the instruction should only invoke tools (e.g., displayMedia) without generating follow-up text.",
                                                          "type": "boolean"
                                                        },
                                                        "stopAfterFirstToolCall": {
                                                          "description": "When true and a single tool is forced with text suppressed, the instruction stops after the first successful tool call. Defaults to false, which allows the tool to be called across multiple steps.",
                                                          "type": "boolean"
                                                        },
                                                        "internal": {
                                                          "description": "When true, this node is an intermediate step: its text/structured output is NOT shown to the user (not streamed, not persisted as a visible message part) and is only captured into the node's outputVar for downstream nodes. Reasoning and tool-call activity chips remain visible. Use for internal hand-offs (e.g. tool-driven data synthesis a later node consumes); the user-facing reply should come from a later, non-internal node.",
                                                          "type": "boolean"
                                                        },
                                                        "outputSchema": {
                                                          "description": "JSON Schema for structured output. When provided, the LLM will output valid JSON matching this schema instead of free-form text.",
                                                          "type": "object",
                                                          "properties": {
                                                            "type": {
                                                              "description": "JSON Schema type, must be \"object\" for structured output.",
                                                              "type": "string",
                                                              "const": "object"
                                                            },
                                                            "properties": {
                                                              "description": "Schema properties defining the expected output structure.",
                                                              "type": "object",
                                                              "propertyNames": {
                                                                "type": "string"
                                                              },
                                                              "additionalProperties": {}
                                                            },
                                                            "required": {
                                                              "description": "Array of required property names.",
                                                              "type": "array",
                                                              "items": {
                                                                "type": "string"
                                                              }
                                                            },
                                                            "additionalProperties": {
                                                              "description": "Whether to allow additional properties not defined in the schema.",
                                                              "type": "boolean"
                                                            },
                                                            "description": {
                                                              "description": "Description of the expected output to guide the LLM.",
                                                              "type": "string"
                                                            }
                                                          },
                                                          "required": [
                                                            "type",
                                                            "properties"
                                                          ]
                                                        },
                                                        "grounding": {
                                                          "description": "Model-side grounding for this node. Only Google Search is available today.",
                                                          "type": "object",
                                                          "properties": {
                                                            "googleSearch": {
                                                              "description": "Enable Google Search grounding: the model searches the public web (via Gemini's built-in google_search tool) while executing this instruction and answers from what it finds. Set `{}` to enable with defaults. The node result then carries `grounding` — the queries Google ran and the sources it cited, each with the resolved article URL, its domain and the passages of the reply it supports — readable downstream as `nodes.<nodeId>.grounding` in javascript nodes and templates; the text/JSON reply itself still flows through outputVar as usual. With an outputSchema the search runs first and the JSON is synthesized afterwards with the numbered source list, so declare a `sourceIds` or `url` field if you want citations inside the structured output. Incompatible with toolChoiceMode \"tool\" and with suppressTextResponse (a forced tool call and Google Search in one request returns an empty reply); with toolChoiceMode \"none\" the node still searches but calls no other tool. Each prompt costs Google one search query per query the model decides to run (usually 4–10), billed per query beyond the project's free tier.",
                                                              "type": "object",
                                                              "properties": {
                                                                "excludeDomains": {
                                                                  "description": "Domains Google Search must not ground on, e.g. [\"youtube.com\", \"reddit.com\"]. A domain excludes its subdomains too.",
                                                                  "type": "array",
                                                                  "items": {
                                                                    "type": "string"
                                                                  }
                                                                }
                                                              }
                                                            }
                                                          }
                                                        },
                                                        "urlContext": {
                                                          "description": "Gemini URL context: hand the model a list of URLs to READ IN FULL server-side instead of fetching their text into a variable first. The URLs come from the fixed \"urls\" list, from the \"from\" value path, or from both (fixed first). They are appended to the end of the instruction and the provider fetches and reads the pages inside the same call. With an outputSchema the node runs as a SINGLE call (reading and synthesis must share it), so pair it with toolChoiceMode \"none\" unless the node truly needs function tools. Limits: 20 URLs per call (extra ones are dropped and reported as `truncated`), public pages only — paywalls, Google News redirect links and private hosts fail. The model may skip fetching when the URLs sit inside a very long prompt, so prefer a dedicated short reading node over bolting URLs onto a large synthesis prompt. The node output carries `urlContext.{requested,retrieved,unread,truncated,invalid,unresolved,supported,tokens}`. `unread` is the integrity signal — it lists every URL the model did not read, including the ones dropped by the 20-URL cap — so branch on `nodes.<id>.urlContext.unread` for a fallback reader (inside a forEach body it holds only the last item). `unresolved` says the \"from\" path resolved to nothing, `invalid` lists entries that were not http(s) URLs, and `supported` is false when the model could not carry the tool: in those cases nothing was read at all. Retrieved page content is billed as input tokens and added to the node usage as `urlContextTokens`. Gemini 3+ models only.",
                                                          "type": "object",
                                                          "properties": {
                                                            "urls": {
                                                              "description": "Fixed http(s) URLs to read on every run, written out here — for pages that do not change per execution (a status page, a policy, a price list). Combine with \"from\" to read a fixed set plus whatever the run produced; the two lists concatenate, fixed URLs first.",
                                                              "type": "array",
                                                              "items": {
                                                                "type": "string"
                                                              }
                                                            },
                                                            "from": {
                                                              "description": "Dotted VALUE PATH (same resolution as forEach \"over\": workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — e.g. \"paraLer.soUrls\" or \"nodes.pick.result.urls\") to a URL list the run produced: an array of http(s) URL strings, a single URL string, or a JSON-encoded array string. Not a Handlebars template; a path wrapped in {{ }} is accepted and unwrapped.",
                                                              "type": "string",
                                                              "minLength": 1
                                                            }
                                                          }
                                                        }
                                                      },
                                                      "required": [
                                                        "instructions"
                                                      ]
                                                    }
                                                  },
                                                  "required": [
                                                    "actionType",
                                                    "config"
                                                  ]
                                                },
                                                {
                                                  "type": "object",
                                                  "properties": {
                                                    "actionType": {
                                                      "type": "string",
                                                      "const": "TOOL_CALL"
                                                    },
                                                    "config": {
                                                      "type": "object",
                                                      "properties": {
                                                        "toolName": {
                                                          "description": "The name of the common tool to invoke.",
                                                          "type": "string"
                                                        },
                                                        "parameters": {
                                                          "description": "Per-parameter configuration. Keys are parameter names from the tool schema.",
                                                          "type": "object",
                                                          "propertyNames": {
                                                            "type": "string"
                                                          },
                                                          "additionalProperties": {
                                                            "type": "object",
                                                            "properties": {
                                                              "mode": {
                                                                "description": "Whether this parameter is hardcoded (static) or filled by the LLM at runtime (dynamic).",
                                                                "type": "string",
                                                                "enum": [
                                                                  "static",
                                                                  "dynamic"
                                                                ]
                                                              },
                                                              "staticValue": {
                                                                "description": "The fixed value for this parameter. Required when mode is \"static\"."
                                                              },
                                                              "instructions": {
                                                                "description": "Optional guidance for the LLM when filling this parameter (only used when mode is \"dynamic\").",
                                                                "type": "string"
                                                              }
                                                            },
                                                            "required": [
                                                              "mode"
                                                            ]
                                                          }
                                                        },
                                                        "instructions": {
                                                          "description": "General instructions for the LLM when resolving dynamic parameters.",
                                                          "type": "string"
                                                        },
                                                        "skipKnowledgeSearch": {
                                                          "description": "When a node has dynamic parameters, the model is normally forced to call similaritySearch first so parameter values are grounded in the knowledge base, costing one extra model round. Set true for tools that need no knowledge context (for example code execution) to call the configured tool directly. Ignored when every parameter is static, since no model runs at all.",
                                                          "type": "boolean"
                                                        }
                                                      },
                                                      "required": [
                                                        "toolName"
                                                      ]
                                                    }
                                                  },
                                                  "required": [
                                                    "actionType",
                                                    "config"
                                                  ]
                                                }
                                              ]
                                            }
                                          },
                                          "required": [
                                            "delayMinutes",
                                            "action"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "mode",
                                        "transition",
                                        "actionType",
                                        "config"
                                      ]
                                    }
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "subAgent"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this sub-agent node.",
                                      "type": "string"
                                    },
                                    "agentId": {
                                      "description": "The ID of the sub-agent to invoke.",
                                      "type": "string"
                                    },
                                    "instructions": {
                                      "description": "Optional instructions message prepended to the sub-agent conversation. Supports Handlebars interpolation against the parent execution scope: `{{var}}` reads workflow vars, `{{context.x}}` reads contextVars, `{{env.X}}` reads environment, `{{input.text}}` reads the original user input, and `{{nodes.<id>.<path>}}` reads prior node outputs.",
                                      "type": "string"
                                    },
                                    "transition": {
                                      "description": "Optional transitions to continue the flow after the sub-agent returns.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/validateAgentSpec_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type",
                                    "agentId"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "end"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this end node.",
                                      "type": "string"
                                    },
                                    "config": {
                                      "description": "Optional configuration for the end node behavior.",
                                      "type": "object",
                                      "properties": {
                                        "resetConversationHistory": {
                                          "description": "If true, the next user message starts a new conversation with no prior history.",
                                          "type": "boolean"
                                        }
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "state"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this state node.",
                                      "type": "string"
                                    },
                                    "outputVar": {
                                      "description": "Agent-scope get only: variable name that receives the value stored under `config.key` (null when the key has never been written). Downstream templates read it as `{{<outputVar>}}`; transition conditions as `{source:\"vars\", path:\"<outputVar>...\"}`.",
                                      "type": "string"
                                    },
                                    "config": {
                                      "type": "object",
                                      "properties": {
                                        "scope": {
                                          "description": "How long the data lives and who sees it. execution: this run only. session: this conversation (thread) — a NEW conversation starts empty. agent: durable memory shared by every execution of this agent, across conversations — use it to remember things between independent runs. Survives clearCache.",
                                          "type": "string",
                                          "enum": [
                                            "execution",
                                            "session",
                                            "agent"
                                          ]
                                        },
                                        "operation": {
                                          "description": "Agent scope only (default set). set: durably store the `state` entries. get: read the entry under `key` into `outputVar`. Execution/session scopes are always set — their values are injected into templates automatically, so no get is needed.",
                                          "type": "string",
                                          "enum": [
                                            "set",
                                            "get"
                                          ]
                                        },
                                        "key": {
                                          "description": "Agent-scope get: the memory key to read. Supports Handlebars (e.g. \"evidence-{{context.cnpj}}\") so one node can address per-entity entries. Rendered keys are limited to 512 characters.",
                                          "type": "string"
                                        },
                                        "state": {
                                          "description": "Key-value pairs to set (required for set operations). String values support Handlebars. In agent scope the KEYS are templates too (e.g. \"evidence-{{context.cnpj}}\"), each entry is stored as its own durable row, and serialized values are size-capped.",
                                          "type": "object",
                                          "propertyNames": {
                                            "type": "string"
                                          },
                                          "additionalProperties": {}
                                        }
                                      },
                                      "required": [
                                        "scope"
                                      ]
                                    },
                                    "transition": {
                                      "description": "Optional transitions to continue the flow after setting state.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/validateAgentSpec_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type",
                                    "config"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "hub"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this hub node.",
                                      "type": "string"
                                    },
                                    "transition": {
                                      "description": "Transitions to route connections to other nodes.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/validateAgentSpec_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "jump"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this jump node.",
                                      "type": "string"
                                    },
                                    "transition": {
                                      "description": "Target node to jump to unconditionally.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/validateAgentSpec_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "clearCache"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this clear cache node.",
                                      "type": "string"
                                    },
                                    "config": {
                                      "description": "Optional configuration controlling what is cleared.",
                                      "type": "object",
                                      "properties": {
                                        "clearScope": {
                                          "description": "What to clear. executionCache (default): clears only the decision result cache. all: clears the entire session state including user-defined session variables.",
                                          "type": "string",
                                          "enum": [
                                            "executionCache",
                                            "all"
                                          ]
                                        }
                                      }
                                    },
                                    "transition": {
                                      "description": "Optional transitions to continue the flow after clearing cache.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/validateAgentSpec_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "javascript"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this JavaScript node.",
                                      "type": "string"
                                    },
                                    "outputVar": {
                                      "description": "Variable name to store the returned value for downstream nodes. Downstream templates read it as `{{<outputVar>}}`; transition conditions as `{source:\"vars\", path:\"<outputVar>...\"}`.",
                                      "type": "string"
                                    },
                                    "config": {
                                      "type": "object",
                                      "properties": {
                                        "code": {
                                          "description": "JavaScript source executed in a sandboxed QuickJS interpreter. Written as a function body: it receives ({ vars, evaluation, context, env, input, nodes }) and must `return` a JSON-serializable value. Synchronous only — no network, filesystem, require/import, or timers.",
                                          "type": "string"
                                        },
                                        "timeoutMs": {
                                          "description": "CPU deadline in milliseconds. Default 1000, max 10000.",
                                          "type": "integer",
                                          "minimum": 1,
                                          "maximum": 10000
                                        }
                                      },
                                      "required": [
                                        "code"
                                      ]
                                    },
                                    "transition": {
                                      "description": "Optional transitions to continue the flow after the code runs.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/validateAgentSpec_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type",
                                    "config"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "forEach"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this forEach node.",
                                      "type": "string"
                                    },
                                    "over": {
                                      "description": "Dotted path to the array to iterate, resolved against the execution scope: top-level workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — for example \"research.socioAlvos\" or \"nodes.build_plan.result.targets\". This is a VALUE PATH, not a Handlebars template: Handlebars renders to a string, so an array passed through it would arrive as \"[object Object]\". A path wrapped in {{ }} is accepted and unwrapped. If the path does not resolve to an array the node fails loudly instead of iterating a string.",
                                      "type": "string"
                                    },
                                    "as": {
                                      "description": "Variable name bound to the current element inside the body node: \"socio\" makes {{socio.nome}} available to the body's templates. Must not be \"iteration\", which is reserved for the {index, total} binding also exposed to the body.",
                                      "type": "string"
                                    },
                                    "each": {
                                      "description": "The body node, referenced by ID. Must be an action, javascript or subAgent node declared in workflow.nodes with no other incoming transitions, and must not be an entry point. Its own \"transition\" array is ignored — the forEach node owns what happens after every item finishes. decision nodes are rejected because the execution cache is keyed by node ID, so parallel instances would contend for one cache entry.",
                                      "type": "object",
                                      "properties": {
                                        "nodeId": {
                                          "description": "The ID of the node to run once per item.",
                                          "type": "string"
                                        }
                                      },
                                      "required": [
                                        "nodeId"
                                      ]
                                    },
                                    "collectInto": {
                                      "description": "Variable name receiving the per-item results array. Each entry is {index, item, ok, value?, grounding?, error?, errorName?}, where \"value\" is whatever the body node's own outputVar would have held (undefined when the body declares none) and \"grounding\" is that item's Google Search queries and sources when the body is a grounded INSTRUCTIONS node — the same shape a standalone node exposes as nodes.<id>.grounding. Entries stay aligned with the source array by index, including failed items, so a downstream node can tell \"this item returned nothing\" apart from \"this item was never tried\". Omit only if nothing downstream needs the results.",
                                      "type": "string"
                                    },
                                    "maxConcurrency": {
                                      "description": "How many items run at once. Defaults to 5. Raise carefully: per-item parallelism hits provider rate limits well before it hits platform limits.",
                                      "type": "integer",
                                      "minimum": 1,
                                      "maximum": 20
                                    },
                                    "transition": {
                                      "description": "Transitions to continue the flow after every item has finished.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/validateAgentSpec_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type",
                                    "over",
                                    "as",
                                    "each"
                                  ]
                                }
                              ]
                            }
                          }
                        },
                        "required": [
                          "toolName",
                          "toolDescription",
                          "entryPoints",
                          "nodes"
                        ]
                      },
                      "tools": {
                        "deprecated": true,
                        "description": "Deprecated and ignored. Tool availability is configured by the application, not the agent spec.",
                        "type": "array",
                        "items": {}
                      },
                      "metadata": {
                        "description": "Arbitrary metadata for custom extensions. Not used by the execution engine.",
                        "type": "object",
                        "propertyNames": {
                          "type": "string"
                        },
                        "additionalProperties": {}
                      }
                    },
                    "required": [
                      "version",
                      "name",
                      "prompt",
                      "workflow"
                    ]
                  }
                },
                "required": [
                  "spec"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The spec is valid (warnings/mustFix may be non-empty)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "valid": {
                      "description": "Whether the spec passed AgentSpecV2 schema validation.",
                      "type": "boolean"
                    },
                    "errors": {
                      "description": "Formatted zod error tree describing the schema violations. Only present when `valid` is false."
                    },
                    "warnings": {
                      "description": "Non-blocking structural advisories, such as orphan nodes, transitions to non-existent nodes or a missing entry point. The spec can still be saved and published.",
                      "examples": [
                        [
                          "Node \"review\" has a transition to non-existent node \"done\""
                        ]
                      ],
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "mustFix": {
                      "description": "Blocking defects that must be fixed before the agent can run correctly, such as broken Handlebars templates or invalid decision-node routing.",
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "valid",
                    "warnings",
                    "mustFix"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON or schema-invalid spec",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "valid": {
                      "description": "Whether the spec passed AgentSpecV2 schema validation.",
                      "type": "boolean"
                    },
                    "errors": {
                      "description": "Formatted zod error tree describing the schema violations. Only present when `valid` is false."
                    },
                    "warnings": {
                      "description": "Non-blocking structural advisories, such as orphan nodes, transitions to non-existent nodes or a missing entry point. The spec can still be saved and published.",
                      "examples": [
                        [
                          "Node \"review\" has a transition to non-existent node \"done\""
                        ]
                      ],
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "mustFix": {
                      "description": "Blocking defects that must be fixed before the agent can run correctly, such as broken Handlebars templates or invalid decision-node routing.",
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "valid",
                    "warnings",
                    "mustFix"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/evals/schema/": {
      "get": {
        "operationId": "getAgentEvalSpecJsonSchema",
        "summary": "Get the AgentEvalSpec JSON Schema",
        "tags": [
          "agents"
        ],
        "description": "Returns the JSON Schema (draft 2020-12) of the agent eval spec, derived from the canonical zod definition. Served as `application/schema+json` with a public cache policy.",
        "responses": {
          "200": {
            "description": "The AgentEvalSpec JSON Schema document"
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/": {
      "get": {
        "operationId": "getAgent",
        "summary": "Get an agent",
        "tags": [
          "agents"
        ],
        "description": "Returns one agent in the same item shape as the `GET /api/agents/` list.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent addressed by the path.",
            "schema": {
              "examples": [
                "cmc4v8xq10001l708h2vxk9d3"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The agent",
            "content": {
              "application/json": {
                "schema": {
                  "description": "An agent. Additional fields from the underlying agent model may be present.",
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "The agent's unique id.",
                      "examples": [
                        "cmc4v8xq10001l708h2vxk9d3"
                      ],
                      "type": "string"
                    },
                    "name": {
                      "description": "The agent's display name. Null when the agent has no name yet.",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "type": {
                      "description": "The agent type: `CUSTOM`, `DOCUMENT_INSIGHTS` or `QUESTION_ANSWERING`.",
                      "examples": [
                        "CUSTOM"
                      ],
                      "type": "string",
                      "enum": [
                        "DOCUMENT_INSIGHTS",
                        "QUESTION_ANSWERING",
                        "CUSTOM"
                      ]
                    },
                    "applicationId": {
                      "description": "Id of the application the agent belongs to. Null for company-scoped agents.",
                      "examples": [
                        42
                      ],
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "name",
                    "type",
                    "applicationId"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateAgent",
        "summary": "Update agent metadata",
        "tags": [
          "agents"
        ],
        "description": "Updates only the canonical agent name and description. This idempotent operation never creates a draft version or changes publication.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent addressed by the path.",
            "schema": {
              "examples": [
                "cmc4v8xq10001l708h2vxk9d3"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "applicationId": {
                        "description": "Positive integer id of the application that scopes this operation.",
                        "type": "integer",
                        "exclusiveMinimum": 0,
                        "maximum": 9007199254740991
                      },
                      "name": {
                        "description": "New non-empty display name.",
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 255
                      },
                      "description": {
                        "description": "New description, or null to clear it.",
                        "anyOf": [
                          {
                            "type": "string",
                            "maxLength": 1000
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "required": [
                      "applicationId",
                      "name"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "properties": {
                      "applicationId": {
                        "description": "Positive integer id of the application that scopes this operation.",
                        "type": "integer",
                        "exclusiveMinimum": 0,
                        "maximum": 9007199254740991
                      },
                      "name": {
                        "description": "New non-empty display name.",
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 255
                      },
                      "description": {
                        "description": "New description, or null to clear it.",
                        "anyOf": [
                          {
                            "type": "string",
                            "maxLength": 1000
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "required": [
                      "applicationId",
                      "description"
                    ],
                    "additionalProperties": false
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The canonical metadata after the idempotent update.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "applicationId": {
                      "type": "integer",
                      "exclusiveMinimum": 0,
                      "maximum": 9007199254740991
                    },
                    "name": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "description": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "changed": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "id",
                    "applicationId",
                    "name",
                    "description",
                    "changed"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid path or metadata body",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Agent not found in the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteAgent",
        "summary": "Delete custom agent",
        "tags": [
          "agents"
        ],
        "description": "Removes a custom agent from availability and disables its automation while preserving its execution and conversation history. Repeating the request is idempotent and retries scheduler cleanup. The `applicationId` query parameter is optional: when omitted, it is derived from the agent itself.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent addressed by the path.",
            "schema": {
              "examples": [
                "cmc4v8xq10001l708h2vxk9d3"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application the agent belongs to. When omitted, it is derived from the agent itself; when given, the agent must belong to that application.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The resulting tombstone state.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "deleted": {
                      "description": "True only when this request created the tombstone.",
                      "type": "boolean"
                    },
                    "deletedAt": {
                      "description": "Timestamp of the original tombstone.",
                      "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))$"
                    },
                    "agentId": {
                      "type": "string"
                    },
                    "applicationId": {
                      "type": "integer",
                      "exclusiveMinimum": 0,
                      "maximum": 9007199254740991
                    }
                  },
                  "required": [
                    "success",
                    "deleted",
                    "deletedAt",
                    "agentId",
                    "applicationId"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid applicationId query parameter",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Custom agent not found in the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/enabled/": {
      "put": {
        "operationId": "setAgentEnabled",
        "summary": "Set agent enabled state",
        "tags": [
          "agents"
        ],
        "description": "Sets the requested absolute enabled state. Repeating the current state is an idempotent no-op and never changes publication, routines, or history.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent addressed by the path.",
            "schema": {
              "examples": [
                "cmc4v8xq10001l708h2vxk9d3"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "applicationId": {
                    "description": "Positive integer id of the application that scopes this operation.",
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  "enabled": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "applicationId",
                  "enabled"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The requested enabled state after the idempotent operation.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "applicationId": {
                      "type": "integer",
                      "exclusiveMinimum": 0,
                      "maximum": 9007199254740991
                    },
                    "enabled": {
                      "type": "boolean"
                    },
                    "changed": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "id",
                    "applicationId",
                    "enabled",
                    "changed"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid path or enabled-state body",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Agent not found in the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/spec/": {
      "put": {
        "operationId": "updateAgentSpec",
        "summary": "Replace complete agent draft spec",
        "tags": [
          "agents"
        ],
        "description": "Replaces the full draft AgentSpec V2; it is not a patch and never publishes. The path agentId overwrites spec.id. In this REST endpoint Agent.name is canonical: update the agent name with updateAgent first, then submit the same normalized spec.name.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent addressed by the path.",
            "schema": {
              "examples": [
                "cmc4v8xq10001l708h2vxk9d3"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "applicationId": {
                    "description": "Positive integer id of the application that scopes this operation.",
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  "spec": {
                    "description": "Complete AgentSpec V2 replacement. The path agentId is canonical and overwrites spec.id.",
                    "type": "object",
                    "properties": {
                      "version": {
                        "description": "Schema version. Must be \"2.0\".",
                        "type": "string",
                        "const": "2.0"
                      },
                      "id": {
                        "description": "Unique identifier for this agent. Auto-generated if not provided.",
                        "type": "string"
                      },
                      "name": {
                        "description": "Human-readable name of the agent.",
                        "type": "string"
                      },
                      "prompt": {
                        "description": "System instructions for the agent. Can be a single string or an array of strings joined at runtime.",
                        "anyOf": [
                          {
                            "type": "string",
                            "minLength": 1
                          },
                          {
                            "minItems": 1,
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1
                            }
                          }
                        ]
                      },
                      "llm": {
                        "description": "LLM configuration for the router persona. Optional; uses platform defaults when omitted.",
                        "type": "object",
                        "properties": {
                          "provider": {
                            "description": "The LLM provider identifier (e.g., \"google\", \"openai\").",
                            "type": "string"
                          },
                          "model": {
                            "description": "The model name to use (e.g., \"gemini-2.0-flash\").",
                            "type": "string"
                          },
                          "temperature": {
                            "description": "Sampling temperature (0-2). IGNORED on Gemini 3.x models, which Google deprecated this parameter for on 2026-07-21 — it is accepted and silently discarded, so it no longer makes output more deterministic. Still accepted for older models and for backwards compatibility with existing specs.",
                            "type": "number"
                          },
                          "maxOutputTokens": {
                            "description": "Maximum number of tokens the model can generate.",
                            "type": "number"
                          },
                          "toolChoice": {
                            "description": "Controls how the model uses tools: auto (model decides), required (must use a tool), none (no tools).",
                            "type": "string",
                            "enum": [
                              "auto",
                              "required",
                              "none"
                            ]
                          },
                          "jsonMode": {
                            "description": "If true, the model outputs valid JSON.",
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "provider",
                          "model"
                        ]
                      },
                      "inlineEvaluationCriteria": {
                        "description": "Map of criteria ID to its full definition. Decision nodes reference these by key. These are criteria that have not been persisted to the database yet. During sandbox execution, they are loaded into memory. During publish, they are persisted to the database and this field is cleared.",
                        "type": "object",
                        "propertyNames": {
                          "type": "string"
                        },
                        "additionalProperties": {
                          "type": "object",
                          "properties": {
                            "name": {
                              "description": "Human-readable name of this evaluation criteria. MUST be a non-empty short noun phrase (e.g. \"Real-Estate Availability Intent\"). Empty strings are forbidden.",
                              "type": "string"
                            },
                            "type": {
                              "description": "The evaluation criteria type (e.g., CUSTOM, QUALITY_HELPFULNESS).",
                              "type": "string",
                              "enum": [
                                "QUALITY_ENGAGINGNESS",
                                "QUALITY_COHERENCE",
                                "QUALITY_CONSISTENCY",
                                "QUALITY_FLUENCY",
                                "QUALITY_RELEVANCE",
                                "SECURITY_FINANCIAL_DETECTION",
                                "SECURITY_PII_DETECTION",
                                "SECURITY_ANOMALOUS_CONVERSATION",
                                "PERSONALITY_EXTRAVERSION",
                                "PERSONALITY_OPEN_TO_EXPERIENCE",
                                "PERSONALITY_CONSCIENTIOUSNESS",
                                "PERSONALITY_AGREEABLENESS",
                                "PERSONALITY_NEUROTICISM",
                                "PERSONALITY_OTHER",
                                "DOCUMENT_INSIGHTS",
                                "CUSTOM"
                              ]
                            },
                            "evaluationCriteria": {
                              "description": "REQUIRED non-empty instruction the evaluator follows to assess the input. One or two sentences in plain language: what to assess, and (if structuredDataParams is set) how to populate each declared field. Example: \"Decide whether the user is asking about real-estate availability. Set isAvailability to true only when the user is clearly asking whether a property is available; otherwise false.\" Empty strings, null, or omission make the reasoning useless and are forbidden.",
                              "type": "string"
                            },
                            "evaluationSteps": {
                              "description": "Ordered evaluation steps for the criteria.",
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "evaluationParams": {
                              "description": "Parameters used during evaluation (e.g., INPUT, CONTEXT).",
                              "type": "array",
                              "items": {
                                "type": "string",
                                "enum": [
                                  "INPUT",
                                  "ACTUAL_OUTPUT",
                                  "EXPECTED_OUTPUT",
                                  "CONTEXT",
                                  "RETRIEVAL_CONTEXT",
                                  "EXECUTION_CONTEXT"
                                ]
                              }
                            },
                            "structuredDataParams": {
                              "description": "Map of field name to a natural-language description of what to extract. The description should encode both the type and the legal values, e.g. \"true if the user is asking about real-estate availability, false otherwise\" (boolean), \"one of: AVAILABILITY, PRICING, CONTACT, OTHER\" (enum), or \"numeric score 1-5 reflecting urgency\" (number). Each declared field becomes a routing key accessible from transition conditions as \"evaluation.structuredData.<field>\" (and is also flattened into top-level vars for action templates). Prefer this for routing on what the user meant or asked; use scores.mean for confidence/quality routing.",
                              "anyOf": [
                                {
                                  "type": "object",
                                  "propertyNames": {
                                    "type": "string"
                                  },
                                  "additionalProperties": {}
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "metadata": {
                              "description": "Additional metadata for the criteria.",
                              "anyOf": [
                                {
                                  "type": "object",
                                  "propertyNames": {
                                    "type": "string"
                                  },
                                  "additionalProperties": {}
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "enabled": {
                              "description": "Whether this criteria is enabled. Defaults to true.",
                              "type": "boolean"
                            }
                          },
                          "required": [
                            "name",
                            "type",
                            "evaluationCriteria"
                          ]
                        }
                      },
                      "workflow": {
                        "description": "The workflow definition including entry points and execution nodes.",
                        "type": "object",
                        "properties": {
                          "toolName": {
                            "description": "The tool name used to invoke this agent in the workflow.",
                            "type": "string"
                          },
                          "toolDescription": {
                            "description": "A description of what this agent does, shown to the LLM router.",
                            "type": "string"
                          },
                          "executionTimeoutSeconds": {
                            "description": "Wall-clock ceiling for ONE execution of this workflow, in seconds (30-1800). When the deadline passes the run is aborted — in-flight model calls are cancelled, sub-agents included — and the execution finishes with status TIMED_OUT, with the reason recorded on the nodes that were cut. Optional: an agent that declares nothing keeps the platform behavior (no explicit ceiling). Declare it when the agent legitimately runs for minutes (deep research, long tool chains) so a slow run is never mistaken for a hung one, or when it must never occupy a worker past a known bound. The budget is per attempt: a run resumed after a crash starts a fresh timer.",
                            "type": "integer",
                            "minimum": 30,
                            "maximum": 1800
                          },
                          "entryPoints": {
                            "description": "Entry points into the workflow. MUST contain at least one node ID; an empty array makes the workflow non-executable. When you restructure or rename the first node, update this list in the same operation so it points at the new entry node.",
                            "minItems": 1,
                            "type": "array",
                            "items": {
                              "anyOf": [
                                {
                                  "description": "Node ID to use as an unconditional entry point.",
                                  "type": "string"
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "nodeId": {
                                      "description": "The ID of the entry point node.",
                                      "type": "string"
                                    },
                                    "if": {
                                      "description": "Optional condition that must be met for this entry point to activate.",
                                      "$ref": "#/components/schemas/updateAgentSpec_schema0"
                                    }
                                  },
                                  "required": [
                                    "nodeId"
                                  ]
                                }
                              ]
                            }
                          },
                          "nodes": {
                            "description": "The workflow nodes: decision, action, subAgent, end, state, hub, jump, clearCache, javascript, or forEach.",
                            "type": "array",
                            "items": {
                              "anyOf": [
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "decision"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this decision node.",
                                      "type": "string"
                                    },
                                    "evaluationCriteria": {
                                      "description": "Evaluation criteria IDs (string references) or inline criteria objects.",
                                      "type": "array",
                                      "items": {
                                        "anyOf": [
                                          {
                                            "type": "string"
                                          },
                                          {
                                            "type": "object",
                                            "properties": {
                                              "id": {
                                                "type": "string"
                                              },
                                              "name": {
                                                "description": "Required non-empty short human-readable name for this criterion (e.g. \"Real-Estate Availability Intent\"). Never an empty string.",
                                                "type": "string"
                                              },
                                              "type": {
                                                "type": "string",
                                                "enum": [
                                                  "QUALITY_ENGAGINGNESS",
                                                  "QUALITY_COHERENCE",
                                                  "QUALITY_CONSISTENCY",
                                                  "QUALITY_FLUENCY",
                                                  "QUALITY_RELEVANCE",
                                                  "SECURITY_FINANCIAL_DETECTION",
                                                  "SECURITY_PII_DETECTION",
                                                  "SECURITY_ANOMALOUS_CONVERSATION",
                                                  "PERSONALITY_EXTRAVERSION",
                                                  "PERSONALITY_OPEN_TO_EXPERIENCE",
                                                  "PERSONALITY_CONSCIENTIOUSNESS",
                                                  "PERSONALITY_AGREEABLENESS",
                                                  "PERSONALITY_NEUROTICISM",
                                                  "PERSONALITY_OTHER",
                                                  "DOCUMENT_INSIGHTS",
                                                  "CUSTOM"
                                                ]
                                              },
                                              "evaluationCriteria": {
                                                "description": "REQUIRED non-empty instruction telling the evaluator what to assess. One or two sentences in plain language: what to evaluate, and — when structuredDataParams is set — how to populate each declared field. Empty strings, null, or omission are forbidden; an empty description leaves the reasoning useless. Example: \"Decide whether the user is asking about real-estate availability. Set isAvailability to true only when the user is clearly asking whether a property is available; otherwise false.\"",
                                                "type": "string"
                                              },
                                              "evaluationSteps": {
                                                "type": "array",
                                                "items": {
                                                  "type": "string"
                                                }
                                              },
                                              "structuredDataParams": {
                                                "anyOf": [
                                                  {
                                                    "type": "object",
                                                    "propertyNames": {
                                                      "type": "string"
                                                    },
                                                    "additionalProperties": {}
                                                  },
                                                  {
                                                    "type": "null"
                                                  }
                                                ]
                                              },
                                              "metadata": {
                                                "anyOf": [
                                                  {
                                                    "type": "object",
                                                    "propertyNames": {
                                                      "type": "string"
                                                    },
                                                    "additionalProperties": {}
                                                  },
                                                  {
                                                    "type": "null"
                                                  }
                                                ]
                                              },
                                              "enabled": {
                                                "type": "boolean"
                                              },
                                              "applicationId": {
                                                "type": "number"
                                              },
                                              "evaluationParams": {
                                                "type": "array",
                                                "items": {
                                                  "type": "string",
                                                  "enum": [
                                                    "INPUT",
                                                    "ACTUAL_OUTPUT",
                                                    "EXPECTED_OUTPUT",
                                                    "CONTEXT",
                                                    "RETRIEVAL_CONTEXT",
                                                    "EXECUTION_CONTEXT"
                                                  ]
                                                }
                                              }
                                            },
                                            "required": [
                                              "name",
                                              "type",
                                              "evaluationCriteria"
                                            ]
                                          }
                                        ]
                                      }
                                    },
                                    "transition": {
                                      "description": "Transitions to other nodes based on evaluation results.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/updateAgentSpec_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    },
                                    "cachePolicy": {
                                      "description": "Controls execution caching for this decision node across messages in a conversation. auto (default): cache result and use a lightweight guard evaluation to detect staleness. always: always use cached result until explicitly cleared. never: always re-evaluate all criteria every message (disables caching).",
                                      "type": "string",
                                      "enum": [
                                        "auto",
                                        "always",
                                        "never"
                                      ]
                                    },
                                    "selectionPolicy": {
                                      "description": "Controls which enabled criteria are evaluated each message. all (default): every enabled criterion runs. contextual: a lightweight router selects only the criteria relevant to the current input and conversation state; the rest are skipped. Skipped criteria are not evaluated, so their structuredData fields are absent downstream (route on them with the \"exists\"/\"notExists\" operators) and scores.mean reflects only the criteria that ran.",
                                      "type": "string",
                                      "enum": [
                                        "all",
                                        "contextual"
                                      ]
                                    },
                                    "alwaysRunCriteria": {
                                      "description": "Only used when selectionPolicy is \"contextual\": IDs of evaluation criteria that always run (they bypass the router); every other criterion is AI-selected per message. Use this to pin extractors whose structuredData a downstream node depends on. Ignored when selectionPolicy is \"all\".",
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    },
                                    "contextualSelectionPrompt": {
                                      "description": "Only used when selectionPolicy is \"contextual\": extra author guidance appended to the built-in router prompt to steer which criteria it picks (e.g. \"prefer running Consultar NFSe whenever the user mentions a nota fiscal, even indirectly\"). It augments the router — it does not replace its output contract or the safe fallback of running everything. Ignored when selectionPolicy is \"all\".",
                                      "type": "string"
                                    },
                                    "routingPolicy": {
                                      "description": "How many REASONINGS (criteria) may win the routing on this node per message. all (default): every matching conditional transition fires in parallel. bestReasoning: only the highest-scoring reasoning wins — ALL matched transitions whose condition is anchored on it fire (they are that reasoning's flow), everything anchored on other reasonings is suppressed. topReasonings: like bestReasoning but the best `maxReasonings` reasonings win. A matched transition is anchored on the highest-scoring criterion its condition references (via \"resultsById.<id>.score\" paths, at any nesting). Score ties between reasonings break by position in this node's evaluationCriteria list (earlier wins) — reorder the list to set priority. Matched transitions that reference NO criterion score (pure structuredData/context/state conditions) are outside the competition and always fire, like \"default\" and unconditional transitions. Criteria evaluation is unaffected — this arbitrates AFTER scoring, so it is the reliable way to get \"only one reasoning wins\" (independent per-criterion evaluations cannot be prompted into exclusivity).",
                                      "type": "string",
                                      "enum": [
                                        "all",
                                        "bestReasoning",
                                        "topReasonings"
                                      ]
                                    },
                                    "maxReasonings": {
                                      "description": "Only used when routingPolicy is \"topReasonings\": how many of the highest-scoring reasonings win the routing. Ignored for other policies (\"bestReasoning\" is exactly maxReasonings = 1).",
                                      "type": "integer",
                                      "minimum": 1,
                                      "maximum": 9007199254740991
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type",
                                    "evaluationCriteria",
                                    "transition"
                                  ]
                                },
                                {
                                  "oneOf": [
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "action"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this action node.",
                                          "type": "string"
                                        },
                                        "mode": {
                                          "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                          "type": "string",
                                          "enum": [
                                            "sync",
                                            "async"
                                          ]
                                        },
                                        "outputVar": {
                                          "description": "Variable name to store the action output for use by downstream nodes.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Transitions to other nodes after this action completes.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/updateAgentSpec_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        },
                                        "actionType": {
                                          "type": "string",
                                          "const": "INSTRUCTIONS"
                                        },
                                        "config": {
                                          "type": "object",
                                          "properties": {
                                            "instructions": {
                                              "description": "The instructions for the LLM to execute.",
                                              "type": "string"
                                            },
                                            "modelTier": {
                                              "description": "The model tier to use for this instruction. Defaults to regular.",
                                              "type": "string",
                                              "enum": [
                                                "lite",
                                                "regular",
                                                "pro"
                                              ]
                                            },
                                            "thinkingEffortPct": {
                                              "description": "Thinking effort percentage (0-100) controlling how much reasoning the model applies.",
                                              "type": "number",
                                              "minimum": 0,
                                              "maximum": 100
                                            },
                                            "maxOutputTokens": {
                                              "description": "Maximum tokens the model may generate for this node. On thinking models the budget is SHARED between reasoning and output — reasoning routinely consumes most of it — so a node whose structured output is truncated is usually better served by lowering thinkingEffortPct than by raising this. Defaults to the model maximum when omitted.",
                                              "type": "integer",
                                              "minimum": 1,
                                              "maximum": 9007199254740991
                                            },
                                            "maxRetries": {
                                              "description": "How many times this node retries a failed model call. Defaults to 2 when the node has an outputSchema and 5 otherwise. Raise it for nodes whose long outputs are exposed to dropped provider streams; it does not help failures the model reproduces deterministically.",
                                              "type": "integer",
                                              "minimum": 1,
                                              "maximum": 10
                                            },
                                            "toolChoiceMode": {
                                              "description": "Tool selection mode for this instruction. Defaults to auto when omitted.",
                                              "type": "string",
                                              "enum": [
                                                "auto",
                                                "none",
                                                "tool",
                                                "tools"
                                              ]
                                            },
                                            "toolChoiceToolName": {
                                              "description": "When toolChoiceMode is \"tool\", the specific tool name to force.",
                                              "type": "string"
                                            },
                                            "toolChoiceToolNames": {
                                              "description": "When toolChoiceMode is \"tools\", the list of allowed tool names.",
                                              "type": "array",
                                              "items": {
                                                "type": "string"
                                              }
                                            },
                                            "suppressTextResponse": {
                                              "description": "When true, text output from the LLM is suppressed and only tool-call results are emitted. Useful when the instruction should only invoke tools (e.g., displayMedia) without generating follow-up text.",
                                              "type": "boolean"
                                            },
                                            "stopAfterFirstToolCall": {
                                              "description": "When true and a single tool is forced with text suppressed, the instruction stops after the first successful tool call. Defaults to false, which allows the tool to be called across multiple steps.",
                                              "type": "boolean"
                                            },
                                            "internal": {
                                              "description": "When true, this node is an intermediate step: its text/structured output is NOT shown to the user (not streamed, not persisted as a visible message part) and is only captured into the node's outputVar for downstream nodes. Reasoning and tool-call activity chips remain visible. Use for internal hand-offs (e.g. tool-driven data synthesis a later node consumes); the user-facing reply should come from a later, non-internal node.",
                                              "type": "boolean"
                                            },
                                            "outputSchema": {
                                              "description": "JSON Schema for structured output. When provided, the LLM will output valid JSON matching this schema instead of free-form text.",
                                              "type": "object",
                                              "properties": {
                                                "type": {
                                                  "description": "JSON Schema type, must be \"object\" for structured output.",
                                                  "type": "string",
                                                  "const": "object"
                                                },
                                                "properties": {
                                                  "description": "Schema properties defining the expected output structure.",
                                                  "type": "object",
                                                  "propertyNames": {
                                                    "type": "string"
                                                  },
                                                  "additionalProperties": {}
                                                },
                                                "required": {
                                                  "description": "Array of required property names.",
                                                  "type": "array",
                                                  "items": {
                                                    "type": "string"
                                                  }
                                                },
                                                "additionalProperties": {
                                                  "description": "Whether to allow additional properties not defined in the schema.",
                                                  "type": "boolean"
                                                },
                                                "description": {
                                                  "description": "Description of the expected output to guide the LLM.",
                                                  "type": "string"
                                                }
                                              },
                                              "required": [
                                                "type",
                                                "properties"
                                              ]
                                            },
                                            "grounding": {
                                              "description": "Model-side grounding for this node. Only Google Search is available today.",
                                              "type": "object",
                                              "properties": {
                                                "googleSearch": {
                                                  "description": "Enable Google Search grounding: the model searches the public web (via Gemini's built-in google_search tool) while executing this instruction and answers from what it finds. Set `{}` to enable with defaults. The node result then carries `grounding` — the queries Google ran and the sources it cited, each with the resolved article URL, its domain and the passages of the reply it supports — readable downstream as `nodes.<nodeId>.grounding` in javascript nodes and templates; the text/JSON reply itself still flows through outputVar as usual. With an outputSchema the search runs first and the JSON is synthesized afterwards with the numbered source list, so declare a `sourceIds` or `url` field if you want citations inside the structured output. Incompatible with toolChoiceMode \"tool\" and with suppressTextResponse (a forced tool call and Google Search in one request returns an empty reply); with toolChoiceMode \"none\" the node still searches but calls no other tool. Each prompt costs Google one search query per query the model decides to run (usually 4–10), billed per query beyond the project's free tier.",
                                                  "type": "object",
                                                  "properties": {
                                                    "excludeDomains": {
                                                      "description": "Domains Google Search must not ground on, e.g. [\"youtube.com\", \"reddit.com\"]. A domain excludes its subdomains too.",
                                                      "type": "array",
                                                      "items": {
                                                        "type": "string"
                                                      }
                                                    }
                                                  }
                                                }
                                              }
                                            },
                                            "urlContext": {
                                              "description": "Gemini URL context: hand the model a list of URLs to READ IN FULL server-side instead of fetching their text into a variable first. The URLs come from the fixed \"urls\" list, from the \"from\" value path, or from both (fixed first). They are appended to the end of the instruction and the provider fetches and reads the pages inside the same call. With an outputSchema the node runs as a SINGLE call (reading and synthesis must share it), so pair it with toolChoiceMode \"none\" unless the node truly needs function tools. Limits: 20 URLs per call (extra ones are dropped and reported as `truncated`), public pages only — paywalls, Google News redirect links and private hosts fail. The model may skip fetching when the URLs sit inside a very long prompt, so prefer a dedicated short reading node over bolting URLs onto a large synthesis prompt. The node output carries `urlContext.{requested,retrieved,unread,truncated,invalid,unresolved,supported,tokens}`. `unread` is the integrity signal — it lists every URL the model did not read, including the ones dropped by the 20-URL cap — so branch on `nodes.<id>.urlContext.unread` for a fallback reader (inside a forEach body it holds only the last item). `unresolved` says the \"from\" path resolved to nothing, `invalid` lists entries that were not http(s) URLs, and `supported` is false when the model could not carry the tool: in those cases nothing was read at all. Retrieved page content is billed as input tokens and added to the node usage as `urlContextTokens`. Gemini 3+ models only.",
                                              "type": "object",
                                              "properties": {
                                                "urls": {
                                                  "description": "Fixed http(s) URLs to read on every run, written out here — for pages that do not change per execution (a status page, a policy, a price list). Combine with \"from\" to read a fixed set plus whatever the run produced; the two lists concatenate, fixed URLs first.",
                                                  "type": "array",
                                                  "items": {
                                                    "type": "string"
                                                  }
                                                },
                                                "from": {
                                                  "description": "Dotted VALUE PATH (same resolution as forEach \"over\": workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — e.g. \"paraLer.soUrls\" or \"nodes.pick.result.urls\") to a URL list the run produced: an array of http(s) URL strings, a single URL string, or a JSON-encoded array string. Not a Handlebars template; a path wrapped in {{ }} is accepted and unwrapped.",
                                                  "type": "string",
                                                  "minLength": 1
                                                }
                                              }
                                            }
                                          },
                                          "required": [
                                            "instructions"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "mode",
                                        "transition",
                                        "actionType",
                                        "config"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "action"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this action node.",
                                          "type": "string"
                                        },
                                        "mode": {
                                          "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                          "type": "string",
                                          "enum": [
                                            "sync",
                                            "async"
                                          ]
                                        },
                                        "outputVar": {
                                          "description": "Variable name to store the action output for use by downstream nodes.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Transitions to other nodes after this action completes.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/updateAgentSpec_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        },
                                        "actionType": {
                                          "type": "string",
                                          "const": "EMAIL"
                                        },
                                        "config": {
                                          "type": "object",
                                          "properties": {
                                            "to": {
                                              "type": "string"
                                            },
                                            "senderType": {
                                              "type": "string",
                                              "enum": [
                                                "default",
                                                "gmail"
                                              ]
                                            },
                                            "gmailIntegrationId": {
                                              "type": "string"
                                            },
                                            "subject": {
                                              "type": "string"
                                            },
                                            "body": {
                                              "type": "string"
                                            },
                                            "cc": {
                                              "type": "string"
                                            },
                                            "bcc": {
                                              "type": "string"
                                            },
                                            "attachments": {
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "documentId": {
                                                    "type": "number"
                                                  },
                                                  "url": {
                                                    "type": "string"
                                                  },
                                                  "filename": {
                                                    "type": "string"
                                                  }
                                                }
                                              }
                                            },
                                            "templateId": {
                                              "type": "string"
                                            },
                                            "templateName": {
                                              "type": "string"
                                            },
                                            "applicationId": {
                                              "type": "number"
                                            }
                                          },
                                          "required": [
                                            "to",
                                            "subject",
                                            "body"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "mode",
                                        "transition",
                                        "actionType",
                                        "config"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "action"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this action node.",
                                          "type": "string"
                                        },
                                        "mode": {
                                          "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                          "type": "string",
                                          "enum": [
                                            "sync",
                                            "async"
                                          ]
                                        },
                                        "outputVar": {
                                          "description": "Variable name to store the action output for use by downstream nodes.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Transitions to other nodes after this action completes.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/updateAgentSpec_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        },
                                        "actionType": {
                                          "type": "string",
                                          "const": "WEBHOOK"
                                        },
                                        "config": {
                                          "type": "object",
                                          "properties": {
                                            "url": {
                                              "type": "string"
                                            },
                                            "method": {
                                              "type": "string",
                                              "enum": [
                                                "GET",
                                                "POST",
                                                "PUT",
                                                "PATCH",
                                                "DELETE"
                                              ]
                                            },
                                            "headers": {
                                              "type": "object",
                                              "propertyNames": {
                                                "type": "string"
                                              },
                                              "additionalProperties": {
                                                "type": "string"
                                              }
                                            },
                                            "queryParams": {
                                              "type": "object",
                                              "propertyNames": {
                                                "type": "string"
                                              },
                                              "additionalProperties": {
                                                "type": "string"
                                              }
                                            },
                                            "body": {
                                              "type": "string"
                                            },
                                            "timeout": {
                                              "type": "number"
                                            },
                                            "responseMode": {
                                              "description": "How to decode the response body. \"json\" (default): parse as JSON/text and expose via varsDelta. \"attachment\": read as binary bytes for multimodal input (e.g. PDFs, images).",
                                              "type": "string",
                                              "enum": [
                                                "json",
                                                "attachment"
                                              ]
                                            },
                                            "asMessage": {
                                              "description": "When true, append the response to the conversation as a new user message so downstream LLM nodes see it. In \"attachment\" mode the message carries a file content part; in \"json\" mode it carries the stringified body as text. Defaults to false — preserving the historical behavior where webhook responses only flow through varsDelta.",
                                              "type": "boolean"
                                            },
                                            "suppressNoResponseFallback": {
                                              "description": "Marks the webhook as a fire-and-forget trigger: the conversation is meant to end here, with the rest happening on the receiving system. When the call succeeds and the turn finishes without sending anything to the user, the channel skips its automatic \"sorry, something went wrong\" fallback message. A failed call (HTTP >= 400) still gets the fallback, since the user is then left waiting for nothing.",
                                              "type": "boolean"
                                            }
                                          },
                                          "required": [
                                            "url",
                                            "method"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "mode",
                                        "transition",
                                        "actionType",
                                        "config"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "action"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this action node.",
                                          "type": "string"
                                        },
                                        "mode": {
                                          "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                          "type": "string",
                                          "enum": [
                                            "sync",
                                            "async"
                                          ]
                                        },
                                        "outputVar": {
                                          "description": "Variable name to store the action output for use by downstream nodes.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Transitions to other nodes after this action completes.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/updateAgentSpec_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        },
                                        "actionType": {
                                          "type": "string",
                                          "const": "DOCUMENT_TEMPLATE"
                                        },
                                        "config": {
                                          "type": "object",
                                          "properties": {
                                            "templateId": {
                                              "type": "string"
                                            },
                                            "templateName": {
                                              "type": "string"
                                            },
                                            "sendEmail": {
                                              "type": "boolean"
                                            },
                                            "sendWhatsApp": {
                                              "type": "boolean"
                                            },
                                            "recipientEmail": {
                                              "type": "string"
                                            }
                                          },
                                          "required": [
                                            "templateId"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "mode",
                                        "transition",
                                        "actionType",
                                        "config"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "action"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this action node.",
                                          "type": "string"
                                        },
                                        "mode": {
                                          "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                          "type": "string",
                                          "enum": [
                                            "sync",
                                            "async"
                                          ]
                                        },
                                        "outputVar": {
                                          "description": "Variable name to store the action output for use by downstream nodes.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Transitions to other nodes after this action completes.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/updateAgentSpec_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        },
                                        "actionType": {
                                          "type": "string",
                                          "const": "TOOL_CALL"
                                        },
                                        "config": {
                                          "type": "object",
                                          "properties": {
                                            "toolName": {
                                              "description": "The name of the common tool to invoke.",
                                              "type": "string"
                                            },
                                            "parameters": {
                                              "description": "Per-parameter configuration. Keys are parameter names from the tool schema.",
                                              "type": "object",
                                              "propertyNames": {
                                                "type": "string"
                                              },
                                              "additionalProperties": {
                                                "type": "object",
                                                "properties": {
                                                  "mode": {
                                                    "description": "Whether this parameter is hardcoded (static) or filled by the LLM at runtime (dynamic).",
                                                    "type": "string",
                                                    "enum": [
                                                      "static",
                                                      "dynamic"
                                                    ]
                                                  },
                                                  "staticValue": {
                                                    "description": "The fixed value for this parameter. Required when mode is \"static\"."
                                                  },
                                                  "instructions": {
                                                    "description": "Optional guidance for the LLM when filling this parameter (only used when mode is \"dynamic\").",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "mode"
                                                ]
                                              }
                                            },
                                            "instructions": {
                                              "description": "General instructions for the LLM when resolving dynamic parameters.",
                                              "type": "string"
                                            },
                                            "skipKnowledgeSearch": {
                                              "description": "When a node has dynamic parameters, the model is normally forced to call similaritySearch first so parameter values are grounded in the knowledge base, costing one extra model round. Set true for tools that need no knowledge context (for example code execution) to call the configured tool directly. Ignored when every parameter is static, since no model runs at all.",
                                              "type": "boolean"
                                            }
                                          },
                                          "required": [
                                            "toolName"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "mode",
                                        "transition",
                                        "actionType",
                                        "config"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Unique identifier for this node.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "type": "string",
                                          "const": "action"
                                        },
                                        "label": {
                                          "description": "Human-readable label for this action node.",
                                          "type": "string"
                                        },
                                        "mode": {
                                          "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                          "type": "string",
                                          "enum": [
                                            "sync",
                                            "async"
                                          ]
                                        },
                                        "outputVar": {
                                          "description": "Variable name to store the action output for use by downstream nodes.",
                                          "type": "string"
                                        },
                                        "transition": {
                                          "description": "Transitions to other nodes after this action completes.",
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "if": {
                                                "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                "$ref": "#/components/schemas/updateAgentSpec_schema0"
                                              },
                                              "default": {
                                                "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                "type": "boolean"
                                              },
                                              "to": {
                                                "type": "object",
                                                "properties": {
                                                  "nodeId": {
                                                    "description": "The ID of the target node to transition to.",
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "nodeId"
                                                ]
                                              },
                                              "stop": {
                                                "description": "If true, stop execution after this transition.",
                                                "type": "boolean"
                                              }
                                            },
                                            "required": [
                                              "to"
                                            ]
                                          }
                                        },
                                        "actionType": {
                                          "type": "string",
                                          "const": "FOLLOW_UP"
                                        },
                                        "config": {
                                          "type": "object",
                                          "properties": {
                                            "delayMinutes": {
                                              "description": "Minutes to wait before checking whether to run the inner action. Common presets: 5, 10, 15. Maximum 1440 (24h). Cloud Scheduler is cron-based so the actual fire time is rounded to the next minute boundary.",
                                              "type": "integer",
                                              "minimum": 1,
                                              "maximum": 1440
                                            },
                                            "cancelOnUserMessage": {
                                              "description": "When true (default), skip the inner action if any USER message arrived after the node was reached. Set to false only if the follow-up should fire even after the user has replied.",
                                              "type": "boolean"
                                            },
                                            "cancelOnAssistantMessage": {
                                              "description": "When true (default), skip the inner action if any ASSISTANT text message was sent after the node was reached. Tool-only assistant messages (no text content) do NOT count. Prevents double-pinging when another node already produced a response.",
                                              "type": "boolean"
                                            },
                                            "cancelOnArchive": {
                                              "description": "When true (default), skip the inner action if the thread was archived between scheduling and firing.",
                                              "type": "boolean"
                                            },
                                            "action": {
                                              "description": "The inner action to run when the delay elapses and cancel rules pass. INSTRUCTIONS produces an LLM-generated text message (good for \"Are you still there?\"-style nudges). TOOL_CALL fires a display tool (good for offering options or showing media).",
                                              "oneOf": [
                                                {
                                                  "type": "object",
                                                  "properties": {
                                                    "actionType": {
                                                      "type": "string",
                                                      "const": "INSTRUCTIONS"
                                                    },
                                                    "config": {
                                                      "type": "object",
                                                      "properties": {
                                                        "instructions": {
                                                          "description": "The instructions for the LLM to execute.",
                                                          "type": "string"
                                                        },
                                                        "modelTier": {
                                                          "description": "The model tier to use for this instruction. Defaults to regular.",
                                                          "type": "string",
                                                          "enum": [
                                                            "lite",
                                                            "regular",
                                                            "pro"
                                                          ]
                                                        },
                                                        "thinkingEffortPct": {
                                                          "description": "Thinking effort percentage (0-100) controlling how much reasoning the model applies.",
                                                          "type": "number",
                                                          "minimum": 0,
                                                          "maximum": 100
                                                        },
                                                        "maxOutputTokens": {
                                                          "description": "Maximum tokens the model may generate for this node. On thinking models the budget is SHARED between reasoning and output — reasoning routinely consumes most of it — so a node whose structured output is truncated is usually better served by lowering thinkingEffortPct than by raising this. Defaults to the model maximum when omitted.",
                                                          "type": "integer",
                                                          "minimum": 1,
                                                          "maximum": 9007199254740991
                                                        },
                                                        "maxRetries": {
                                                          "description": "How many times this node retries a failed model call. Defaults to 2 when the node has an outputSchema and 5 otherwise. Raise it for nodes whose long outputs are exposed to dropped provider streams; it does not help failures the model reproduces deterministically.",
                                                          "type": "integer",
                                                          "minimum": 1,
                                                          "maximum": 10
                                                        },
                                                        "toolChoiceMode": {
                                                          "description": "Tool selection mode for this instruction. Defaults to auto when omitted.",
                                                          "type": "string",
                                                          "enum": [
                                                            "auto",
                                                            "none",
                                                            "tool",
                                                            "tools"
                                                          ]
                                                        },
                                                        "toolChoiceToolName": {
                                                          "description": "When toolChoiceMode is \"tool\", the specific tool name to force.",
                                                          "type": "string"
                                                        },
                                                        "toolChoiceToolNames": {
                                                          "description": "When toolChoiceMode is \"tools\", the list of allowed tool names.",
                                                          "type": "array",
                                                          "items": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "suppressTextResponse": {
                                                          "description": "When true, text output from the LLM is suppressed and only tool-call results are emitted. Useful when the instruction should only invoke tools (e.g., displayMedia) without generating follow-up text.",
                                                          "type": "boolean"
                                                        },
                                                        "stopAfterFirstToolCall": {
                                                          "description": "When true and a single tool is forced with text suppressed, the instruction stops after the first successful tool call. Defaults to false, which allows the tool to be called across multiple steps.",
                                                          "type": "boolean"
                                                        },
                                                        "internal": {
                                                          "description": "When true, this node is an intermediate step: its text/structured output is NOT shown to the user (not streamed, not persisted as a visible message part) and is only captured into the node's outputVar for downstream nodes. Reasoning and tool-call activity chips remain visible. Use for internal hand-offs (e.g. tool-driven data synthesis a later node consumes); the user-facing reply should come from a later, non-internal node.",
                                                          "type": "boolean"
                                                        },
                                                        "outputSchema": {
                                                          "description": "JSON Schema for structured output. When provided, the LLM will output valid JSON matching this schema instead of free-form text.",
                                                          "type": "object",
                                                          "properties": {
                                                            "type": {
                                                              "description": "JSON Schema type, must be \"object\" for structured output.",
                                                              "type": "string",
                                                              "const": "object"
                                                            },
                                                            "properties": {
                                                              "description": "Schema properties defining the expected output structure.",
                                                              "type": "object",
                                                              "propertyNames": {
                                                                "type": "string"
                                                              },
                                                              "additionalProperties": {}
                                                            },
                                                            "required": {
                                                              "description": "Array of required property names.",
                                                              "type": "array",
                                                              "items": {
                                                                "type": "string"
                                                              }
                                                            },
                                                            "additionalProperties": {
                                                              "description": "Whether to allow additional properties not defined in the schema.",
                                                              "type": "boolean"
                                                            },
                                                            "description": {
                                                              "description": "Description of the expected output to guide the LLM.",
                                                              "type": "string"
                                                            }
                                                          },
                                                          "required": [
                                                            "type",
                                                            "properties"
                                                          ]
                                                        },
                                                        "grounding": {
                                                          "description": "Model-side grounding for this node. Only Google Search is available today.",
                                                          "type": "object",
                                                          "properties": {
                                                            "googleSearch": {
                                                              "description": "Enable Google Search grounding: the model searches the public web (via Gemini's built-in google_search tool) while executing this instruction and answers from what it finds. Set `{}` to enable with defaults. The node result then carries `grounding` — the queries Google ran and the sources it cited, each with the resolved article URL, its domain and the passages of the reply it supports — readable downstream as `nodes.<nodeId>.grounding` in javascript nodes and templates; the text/JSON reply itself still flows through outputVar as usual. With an outputSchema the search runs first and the JSON is synthesized afterwards with the numbered source list, so declare a `sourceIds` or `url` field if you want citations inside the structured output. Incompatible with toolChoiceMode \"tool\" and with suppressTextResponse (a forced tool call and Google Search in one request returns an empty reply); with toolChoiceMode \"none\" the node still searches but calls no other tool. Each prompt costs Google one search query per query the model decides to run (usually 4–10), billed per query beyond the project's free tier.",
                                                              "type": "object",
                                                              "properties": {
                                                                "excludeDomains": {
                                                                  "description": "Domains Google Search must not ground on, e.g. [\"youtube.com\", \"reddit.com\"]. A domain excludes its subdomains too.",
                                                                  "type": "array",
                                                                  "items": {
                                                                    "type": "string"
                                                                  }
                                                                }
                                                              }
                                                            }
                                                          }
                                                        },
                                                        "urlContext": {
                                                          "description": "Gemini URL context: hand the model a list of URLs to READ IN FULL server-side instead of fetching their text into a variable first. The URLs come from the fixed \"urls\" list, from the \"from\" value path, or from both (fixed first). They are appended to the end of the instruction and the provider fetches and reads the pages inside the same call. With an outputSchema the node runs as a SINGLE call (reading and synthesis must share it), so pair it with toolChoiceMode \"none\" unless the node truly needs function tools. Limits: 20 URLs per call (extra ones are dropped and reported as `truncated`), public pages only — paywalls, Google News redirect links and private hosts fail. The model may skip fetching when the URLs sit inside a very long prompt, so prefer a dedicated short reading node over bolting URLs onto a large synthesis prompt. The node output carries `urlContext.{requested,retrieved,unread,truncated,invalid,unresolved,supported,tokens}`. `unread` is the integrity signal — it lists every URL the model did not read, including the ones dropped by the 20-URL cap — so branch on `nodes.<id>.urlContext.unread` for a fallback reader (inside a forEach body it holds only the last item). `unresolved` says the \"from\" path resolved to nothing, `invalid` lists entries that were not http(s) URLs, and `supported` is false when the model could not carry the tool: in those cases nothing was read at all. Retrieved page content is billed as input tokens and added to the node usage as `urlContextTokens`. Gemini 3+ models only.",
                                                          "type": "object",
                                                          "properties": {
                                                            "urls": {
                                                              "description": "Fixed http(s) URLs to read on every run, written out here — for pages that do not change per execution (a status page, a policy, a price list). Combine with \"from\" to read a fixed set plus whatever the run produced; the two lists concatenate, fixed URLs first.",
                                                              "type": "array",
                                                              "items": {
                                                                "type": "string"
                                                              }
                                                            },
                                                            "from": {
                                                              "description": "Dotted VALUE PATH (same resolution as forEach \"over\": workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — e.g. \"paraLer.soUrls\" or \"nodes.pick.result.urls\") to a URL list the run produced: an array of http(s) URL strings, a single URL string, or a JSON-encoded array string. Not a Handlebars template; a path wrapped in {{ }} is accepted and unwrapped.",
                                                              "type": "string",
                                                              "minLength": 1
                                                            }
                                                          }
                                                        }
                                                      },
                                                      "required": [
                                                        "instructions"
                                                      ]
                                                    }
                                                  },
                                                  "required": [
                                                    "actionType",
                                                    "config"
                                                  ]
                                                },
                                                {
                                                  "type": "object",
                                                  "properties": {
                                                    "actionType": {
                                                      "type": "string",
                                                      "const": "TOOL_CALL"
                                                    },
                                                    "config": {
                                                      "type": "object",
                                                      "properties": {
                                                        "toolName": {
                                                          "description": "The name of the common tool to invoke.",
                                                          "type": "string"
                                                        },
                                                        "parameters": {
                                                          "description": "Per-parameter configuration. Keys are parameter names from the tool schema.",
                                                          "type": "object",
                                                          "propertyNames": {
                                                            "type": "string"
                                                          },
                                                          "additionalProperties": {
                                                            "type": "object",
                                                            "properties": {
                                                              "mode": {
                                                                "description": "Whether this parameter is hardcoded (static) or filled by the LLM at runtime (dynamic).",
                                                                "type": "string",
                                                                "enum": [
                                                                  "static",
                                                                  "dynamic"
                                                                ]
                                                              },
                                                              "staticValue": {
                                                                "description": "The fixed value for this parameter. Required when mode is \"static\"."
                                                              },
                                                              "instructions": {
                                                                "description": "Optional guidance for the LLM when filling this parameter (only used when mode is \"dynamic\").",
                                                                "type": "string"
                                                              }
                                                            },
                                                            "required": [
                                                              "mode"
                                                            ]
                                                          }
                                                        },
                                                        "instructions": {
                                                          "description": "General instructions for the LLM when resolving dynamic parameters.",
                                                          "type": "string"
                                                        },
                                                        "skipKnowledgeSearch": {
                                                          "description": "When a node has dynamic parameters, the model is normally forced to call similaritySearch first so parameter values are grounded in the knowledge base, costing one extra model round. Set true for tools that need no knowledge context (for example code execution) to call the configured tool directly. Ignored when every parameter is static, since no model runs at all.",
                                                          "type": "boolean"
                                                        }
                                                      },
                                                      "required": [
                                                        "toolName"
                                                      ]
                                                    }
                                                  },
                                                  "required": [
                                                    "actionType",
                                                    "config"
                                                  ]
                                                }
                                              ]
                                            }
                                          },
                                          "required": [
                                            "delayMinutes",
                                            "action"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "type",
                                        "mode",
                                        "transition",
                                        "actionType",
                                        "config"
                                      ]
                                    }
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "subAgent"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this sub-agent node.",
                                      "type": "string"
                                    },
                                    "agentId": {
                                      "description": "The ID of the sub-agent to invoke.",
                                      "type": "string"
                                    },
                                    "instructions": {
                                      "description": "Optional instructions message prepended to the sub-agent conversation. Supports Handlebars interpolation against the parent execution scope: `{{var}}` reads workflow vars, `{{context.x}}` reads contextVars, `{{env.X}}` reads environment, `{{input.text}}` reads the original user input, and `{{nodes.<id>.<path>}}` reads prior node outputs.",
                                      "type": "string"
                                    },
                                    "transition": {
                                      "description": "Optional transitions to continue the flow after the sub-agent returns.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/updateAgentSpec_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type",
                                    "agentId"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "end"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this end node.",
                                      "type": "string"
                                    },
                                    "config": {
                                      "description": "Optional configuration for the end node behavior.",
                                      "type": "object",
                                      "properties": {
                                        "resetConversationHistory": {
                                          "description": "If true, the next user message starts a new conversation with no prior history.",
                                          "type": "boolean"
                                        }
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "state"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this state node.",
                                      "type": "string"
                                    },
                                    "outputVar": {
                                      "description": "Agent-scope get only: variable name that receives the value stored under `config.key` (null when the key has never been written). Downstream templates read it as `{{<outputVar>}}`; transition conditions as `{source:\"vars\", path:\"<outputVar>...\"}`.",
                                      "type": "string"
                                    },
                                    "config": {
                                      "type": "object",
                                      "properties": {
                                        "scope": {
                                          "description": "How long the data lives and who sees it. execution: this run only. session: this conversation (thread) — a NEW conversation starts empty. agent: durable memory shared by every execution of this agent, across conversations — use it to remember things between independent runs. Survives clearCache.",
                                          "type": "string",
                                          "enum": [
                                            "execution",
                                            "session",
                                            "agent"
                                          ]
                                        },
                                        "operation": {
                                          "description": "Agent scope only (default set). set: durably store the `state` entries. get: read the entry under `key` into `outputVar`. Execution/session scopes are always set — their values are injected into templates automatically, so no get is needed.",
                                          "type": "string",
                                          "enum": [
                                            "set",
                                            "get"
                                          ]
                                        },
                                        "key": {
                                          "description": "Agent-scope get: the memory key to read. Supports Handlebars (e.g. \"evidence-{{context.cnpj}}\") so one node can address per-entity entries. Rendered keys are limited to 512 characters.",
                                          "type": "string"
                                        },
                                        "state": {
                                          "description": "Key-value pairs to set (required for set operations). String values support Handlebars. In agent scope the KEYS are templates too (e.g. \"evidence-{{context.cnpj}}\"), each entry is stored as its own durable row, and serialized values are size-capped.",
                                          "type": "object",
                                          "propertyNames": {
                                            "type": "string"
                                          },
                                          "additionalProperties": {}
                                        }
                                      },
                                      "required": [
                                        "scope"
                                      ]
                                    },
                                    "transition": {
                                      "description": "Optional transitions to continue the flow after setting state.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/updateAgentSpec_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type",
                                    "config"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "hub"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this hub node.",
                                      "type": "string"
                                    },
                                    "transition": {
                                      "description": "Transitions to route connections to other nodes.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/updateAgentSpec_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "jump"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this jump node.",
                                      "type": "string"
                                    },
                                    "transition": {
                                      "description": "Target node to jump to unconditionally.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/updateAgentSpec_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "clearCache"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this clear cache node.",
                                      "type": "string"
                                    },
                                    "config": {
                                      "description": "Optional configuration controlling what is cleared.",
                                      "type": "object",
                                      "properties": {
                                        "clearScope": {
                                          "description": "What to clear. executionCache (default): clears only the decision result cache. all: clears the entire session state including user-defined session variables.",
                                          "type": "string",
                                          "enum": [
                                            "executionCache",
                                            "all"
                                          ]
                                        }
                                      }
                                    },
                                    "transition": {
                                      "description": "Optional transitions to continue the flow after clearing cache.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/updateAgentSpec_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "javascript"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this JavaScript node.",
                                      "type": "string"
                                    },
                                    "outputVar": {
                                      "description": "Variable name to store the returned value for downstream nodes. Downstream templates read it as `{{<outputVar>}}`; transition conditions as `{source:\"vars\", path:\"<outputVar>...\"}`.",
                                      "type": "string"
                                    },
                                    "config": {
                                      "type": "object",
                                      "properties": {
                                        "code": {
                                          "description": "JavaScript source executed in a sandboxed QuickJS interpreter. Written as a function body: it receives ({ vars, evaluation, context, env, input, nodes }) and must `return` a JSON-serializable value. Synchronous only — no network, filesystem, require/import, or timers.",
                                          "type": "string"
                                        },
                                        "timeoutMs": {
                                          "description": "CPU deadline in milliseconds. Default 1000, max 10000.",
                                          "type": "integer",
                                          "minimum": 1,
                                          "maximum": 10000
                                        }
                                      },
                                      "required": [
                                        "code"
                                      ]
                                    },
                                    "transition": {
                                      "description": "Optional transitions to continue the flow after the code runs.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/updateAgentSpec_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type",
                                    "config"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "Unique identifier for this node.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "const": "forEach"
                                    },
                                    "label": {
                                      "description": "Human-readable label for this forEach node.",
                                      "type": "string"
                                    },
                                    "over": {
                                      "description": "Dotted path to the array to iterate, resolved against the execution scope: top-level workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — for example \"research.socioAlvos\" or \"nodes.build_plan.result.targets\". This is a VALUE PATH, not a Handlebars template: Handlebars renders to a string, so an array passed through it would arrive as \"[object Object]\". A path wrapped in {{ }} is accepted and unwrapped. If the path does not resolve to an array the node fails loudly instead of iterating a string.",
                                      "type": "string"
                                    },
                                    "as": {
                                      "description": "Variable name bound to the current element inside the body node: \"socio\" makes {{socio.nome}} available to the body's templates. Must not be \"iteration\", which is reserved for the {index, total} binding also exposed to the body.",
                                      "type": "string"
                                    },
                                    "each": {
                                      "description": "The body node, referenced by ID. Must be an action, javascript or subAgent node declared in workflow.nodes with no other incoming transitions, and must not be an entry point. Its own \"transition\" array is ignored — the forEach node owns what happens after every item finishes. decision nodes are rejected because the execution cache is keyed by node ID, so parallel instances would contend for one cache entry.",
                                      "type": "object",
                                      "properties": {
                                        "nodeId": {
                                          "description": "The ID of the node to run once per item.",
                                          "type": "string"
                                        }
                                      },
                                      "required": [
                                        "nodeId"
                                      ]
                                    },
                                    "collectInto": {
                                      "description": "Variable name receiving the per-item results array. Each entry is {index, item, ok, value?, grounding?, error?, errorName?}, where \"value\" is whatever the body node's own outputVar would have held (undefined when the body declares none) and \"grounding\" is that item's Google Search queries and sources when the body is a grounded INSTRUCTIONS node — the same shape a standalone node exposes as nodes.<id>.grounding. Entries stay aligned with the source array by index, including failed items, so a downstream node can tell \"this item returned nothing\" apart from \"this item was never tried\". Omit only if nothing downstream needs the results.",
                                      "type": "string"
                                    },
                                    "maxConcurrency": {
                                      "description": "How many items run at once. Defaults to 5. Raise carefully: per-item parallelism hits provider rate limits well before it hits platform limits.",
                                      "type": "integer",
                                      "minimum": 1,
                                      "maximum": 20
                                    },
                                    "transition": {
                                      "description": "Transitions to continue the flow after every item has finished.",
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "if": {
                                            "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                            "$ref": "#/components/schemas/updateAgentSpec_schema0"
                                          },
                                          "default": {
                                            "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                            "type": "boolean"
                                          },
                                          "to": {
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the target node to transition to.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ]
                                          },
                                          "stop": {
                                            "description": "If true, stop execution after this transition.",
                                            "type": "boolean"
                                          }
                                        },
                                        "required": [
                                          "to"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type",
                                    "over",
                                    "as",
                                    "each"
                                  ]
                                }
                              ]
                            }
                          }
                        },
                        "required": [
                          "toolName",
                          "toolDescription",
                          "entryPoints",
                          "nodes"
                        ]
                      },
                      "tools": {
                        "deprecated": true,
                        "description": "Deprecated and ignored. Tool availability is configured by the application, not the agent spec.",
                        "type": "array",
                        "items": {}
                      },
                      "metadata": {
                        "description": "Arbitrary metadata for custom extensions. Not used by the execution engine.",
                        "type": "object",
                        "propertyNames": {
                          "type": "string"
                        },
                        "additionalProperties": {}
                      }
                    },
                    "required": [
                      "version",
                      "name",
                      "prompt",
                      "workflow"
                    ],
                    "additionalProperties": false
                  },
                  "baseVersion": {
                    "description": "Draft artifact version this complete replacement is based on.",
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  "versionName": {
                    "description": "Optional checkpoint label; this operation never publishes.",
                    "type": "string",
                    "minLength": 1
                  }
                },
                "required": [
                  "applicationId",
                  "spec",
                  "baseVersion"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The new draft artifact version.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "agentId": {
                      "type": "string"
                    },
                    "artifactId": {
                      "type": "string"
                    },
                    "version": {
                      "type": "integer",
                      "exclusiveMinimum": 0,
                      "maximum": 9007199254740991
                    },
                    "name": {
                      "type": "string"
                    },
                    "warnings": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "mustFix": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "agentId",
                    "artifactId",
                    "version",
                    "name",
                    "warnings",
                    "mustFix"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid path or complete replacement body",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Agent not found in the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "409": {
            "description": "The base draft version is stale",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "latestVersion": {
                      "type": "integer",
                      "exclusiveMinimum": 0,
                      "maximum": 9007199254740991
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "422": {
            "description": "The spec has blocking mustFix defects and was not persisted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "warnings": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "mustFix": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "error",
                    "warnings",
                    "mustFix"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/export/": {
      "get": {
        "operationId": "exportAgent",
        "summary": "Export an agent bundle",
        "tags": [
          "agents"
        ],
        "description": "Exports the agent (and, recursively, its sub-agents) as a portable bundle with inline evaluation criteria, evals and routines. Served as a JSON file download (`Content-Disposition: attachment`).",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent addressed by the path.",
            "schema": {
              "examples": [
                "cmc4v8xq10001l708h2vxk9d3"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The exported agent bundle as a file download",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "exportVersion": {
                      "description": "Version of the export bundle format. Currently `1`.",
                      "examples": [
                        1
                      ],
                      "type": "number"
                    },
                    "agent": {
                      "description": "The root agent of the bundle.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "Id of the agent in the source environment. On import it is used to find an existing agent to update and to remap sub-agent references.",
                          "examples": [
                            "cmc4v8xq10001l708h2vxk9d3"
                          ],
                          "type": "string"
                        },
                        "name": {
                          "description": "The agent's display name.",
                          "type": "string"
                        },
                        "description": {
                          "description": "The agent's description.",
                          "type": "string"
                        },
                        "spec": {
                          "description": "The agent's AgentSpecV2 workflow spec, with referenced evaluation criteria inlined for portability.",
                          "type": "object",
                          "properties": {
                            "version": {
                              "description": "Schema version. Must be \"2.0\".",
                              "type": "string",
                              "const": "2.0"
                            },
                            "id": {
                              "description": "Unique identifier for this agent. Auto-generated if not provided.",
                              "type": "string"
                            },
                            "name": {
                              "description": "Human-readable name of the agent.",
                              "type": "string"
                            },
                            "prompt": {
                              "description": "System instructions for the agent. Can be a single string or an array of strings joined at runtime.",
                              "anyOf": [
                                {
                                  "type": "string",
                                  "minLength": 1
                                },
                                {
                                  "minItems": 1,
                                  "type": "array",
                                  "items": {
                                    "type": "string",
                                    "minLength": 1
                                  }
                                }
                              ]
                            },
                            "llm": {
                              "description": "LLM configuration for the router persona. Optional; uses platform defaults when omitted.",
                              "type": "object",
                              "properties": {
                                "provider": {
                                  "description": "The LLM provider identifier (e.g., \"google\", \"openai\").",
                                  "type": "string"
                                },
                                "model": {
                                  "description": "The model name to use (e.g., \"gemini-2.0-flash\").",
                                  "type": "string"
                                },
                                "temperature": {
                                  "description": "Sampling temperature (0-2). IGNORED on Gemini 3.x models, which Google deprecated this parameter for on 2026-07-21 — it is accepted and silently discarded, so it no longer makes output more deterministic. Still accepted for older models and for backwards compatibility with existing specs.",
                                  "type": "number"
                                },
                                "maxOutputTokens": {
                                  "description": "Maximum number of tokens the model can generate.",
                                  "type": "number"
                                },
                                "toolChoice": {
                                  "description": "Controls how the model uses tools: auto (model decides), required (must use a tool), none (no tools).",
                                  "type": "string",
                                  "enum": [
                                    "auto",
                                    "required",
                                    "none"
                                  ]
                                },
                                "jsonMode": {
                                  "description": "If true, the model outputs valid JSON.",
                                  "type": "boolean"
                                }
                              },
                              "required": [
                                "provider",
                                "model"
                              ],
                              "additionalProperties": false
                            },
                            "inlineEvaluationCriteria": {
                              "description": "Map of criteria ID to its full definition. Decision nodes reference these by key. These are criteria that have not been persisted to the database yet. During sandbox execution, they are loaded into memory. During publish, they are persisted to the database and this field is cleared.",
                              "type": "object",
                              "propertyNames": {
                                "type": "string"
                              },
                              "additionalProperties": {
                                "type": "object",
                                "properties": {
                                  "name": {
                                    "description": "Human-readable name of this evaluation criteria. MUST be a non-empty short noun phrase (e.g. \"Real-Estate Availability Intent\"). Empty strings are forbidden.",
                                    "type": "string"
                                  },
                                  "type": {
                                    "description": "The evaluation criteria type (e.g., CUSTOM, QUALITY_HELPFULNESS).",
                                    "type": "string",
                                    "enum": [
                                      "QUALITY_ENGAGINGNESS",
                                      "QUALITY_COHERENCE",
                                      "QUALITY_CONSISTENCY",
                                      "QUALITY_FLUENCY",
                                      "QUALITY_RELEVANCE",
                                      "SECURITY_FINANCIAL_DETECTION",
                                      "SECURITY_PII_DETECTION",
                                      "SECURITY_ANOMALOUS_CONVERSATION",
                                      "PERSONALITY_EXTRAVERSION",
                                      "PERSONALITY_OPEN_TO_EXPERIENCE",
                                      "PERSONALITY_CONSCIENTIOUSNESS",
                                      "PERSONALITY_AGREEABLENESS",
                                      "PERSONALITY_NEUROTICISM",
                                      "PERSONALITY_OTHER",
                                      "DOCUMENT_INSIGHTS",
                                      "CUSTOM"
                                    ]
                                  },
                                  "evaluationCriteria": {
                                    "description": "REQUIRED non-empty instruction the evaluator follows to assess the input. One or two sentences in plain language: what to assess, and (if structuredDataParams is set) how to populate each declared field. Example: \"Decide whether the user is asking about real-estate availability. Set isAvailability to true only when the user is clearly asking whether a property is available; otherwise false.\" Empty strings, null, or omission make the reasoning useless and are forbidden.",
                                    "type": "string"
                                  },
                                  "evaluationSteps": {
                                    "description": "Ordered evaluation steps for the criteria.",
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "evaluationParams": {
                                    "description": "Parameters used during evaluation (e.g., INPUT, CONTEXT).",
                                    "type": "array",
                                    "items": {
                                      "type": "string",
                                      "enum": [
                                        "INPUT",
                                        "ACTUAL_OUTPUT",
                                        "EXPECTED_OUTPUT",
                                        "CONTEXT",
                                        "RETRIEVAL_CONTEXT",
                                        "EXECUTION_CONTEXT"
                                      ]
                                    }
                                  },
                                  "structuredDataParams": {
                                    "description": "Map of field name to a natural-language description of what to extract. The description should encode both the type and the legal values, e.g. \"true if the user is asking about real-estate availability, false otherwise\" (boolean), \"one of: AVAILABILITY, PRICING, CONTACT, OTHER\" (enum), or \"numeric score 1-5 reflecting urgency\" (number). Each declared field becomes a routing key accessible from transition conditions as \"evaluation.structuredData.<field>\" (and is also flattened into top-level vars for action templates). Prefer this for routing on what the user meant or asked; use scores.mean for confidence/quality routing.",
                                    "anyOf": [
                                      {
                                        "type": "object",
                                        "propertyNames": {
                                          "type": "string"
                                        },
                                        "additionalProperties": {}
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ]
                                  },
                                  "metadata": {
                                    "description": "Additional metadata for the criteria.",
                                    "anyOf": [
                                      {
                                        "type": "object",
                                        "propertyNames": {
                                          "type": "string"
                                        },
                                        "additionalProperties": {}
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ]
                                  },
                                  "enabled": {
                                    "description": "Whether this criteria is enabled. Defaults to true.",
                                    "type": "boolean"
                                  }
                                },
                                "required": [
                                  "name",
                                  "type",
                                  "evaluationCriteria"
                                ],
                                "additionalProperties": false
                              }
                            },
                            "workflow": {
                              "description": "The workflow definition including entry points and execution nodes.",
                              "type": "object",
                              "properties": {
                                "toolName": {
                                  "description": "The tool name used to invoke this agent in the workflow.",
                                  "type": "string"
                                },
                                "toolDescription": {
                                  "description": "A description of what this agent does, shown to the LLM router.",
                                  "type": "string"
                                },
                                "executionTimeoutSeconds": {
                                  "description": "Wall-clock ceiling for ONE execution of this workflow, in seconds (30-1800). When the deadline passes the run is aborted — in-flight model calls are cancelled, sub-agents included — and the execution finishes with status TIMED_OUT, with the reason recorded on the nodes that were cut. Optional: an agent that declares nothing keeps the platform behavior (no explicit ceiling). Declare it when the agent legitimately runs for minutes (deep research, long tool chains) so a slow run is never mistaken for a hung one, or when it must never occupy a worker past a known bound. The budget is per attempt: a run resumed after a crash starts a fresh timer.",
                                  "type": "integer",
                                  "minimum": 30,
                                  "maximum": 1800
                                },
                                "entryPoints": {
                                  "description": "Entry points into the workflow. MUST contain at least one node ID; an empty array makes the workflow non-executable. When you restructure or rename the first node, update this list in the same operation so it points at the new entry node.",
                                  "minItems": 1,
                                  "type": "array",
                                  "items": {
                                    "anyOf": [
                                      {
                                        "description": "Node ID to use as an unconditional entry point.",
                                        "type": "string"
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "nodeId": {
                                            "description": "The ID of the entry point node.",
                                            "type": "string"
                                          },
                                          "if": {
                                            "description": "Optional condition that must be met for this entry point to activate.",
                                            "$ref": "#/components/schemas/exportAgent_schema0"
                                          }
                                        },
                                        "required": [
                                          "nodeId"
                                        ],
                                        "additionalProperties": false
                                      }
                                    ]
                                  }
                                },
                                "nodes": {
                                  "description": "The workflow nodes: decision, action, subAgent, end, state, hub, jump, clearCache, javascript, or forEach.",
                                  "type": "array",
                                  "items": {
                                    "anyOf": [
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "decision"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this decision node.",
                                            "type": "string"
                                          },
                                          "evaluationCriteria": {
                                            "description": "Evaluation criteria IDs (string references) or inline criteria objects.",
                                            "type": "array",
                                            "items": {
                                              "anyOf": [
                                                {
                                                  "type": "string"
                                                },
                                                {
                                                  "type": "object",
                                                  "properties": {
                                                    "id": {
                                                      "type": "string"
                                                    },
                                                    "name": {
                                                      "description": "Required non-empty short human-readable name for this criterion (e.g. \"Real-Estate Availability Intent\"). Never an empty string.",
                                                      "type": "string"
                                                    },
                                                    "type": {
                                                      "type": "string",
                                                      "enum": [
                                                        "QUALITY_ENGAGINGNESS",
                                                        "QUALITY_COHERENCE",
                                                        "QUALITY_CONSISTENCY",
                                                        "QUALITY_FLUENCY",
                                                        "QUALITY_RELEVANCE",
                                                        "SECURITY_FINANCIAL_DETECTION",
                                                        "SECURITY_PII_DETECTION",
                                                        "SECURITY_ANOMALOUS_CONVERSATION",
                                                        "PERSONALITY_EXTRAVERSION",
                                                        "PERSONALITY_OPEN_TO_EXPERIENCE",
                                                        "PERSONALITY_CONSCIENTIOUSNESS",
                                                        "PERSONALITY_AGREEABLENESS",
                                                        "PERSONALITY_NEUROTICISM",
                                                        "PERSONALITY_OTHER",
                                                        "DOCUMENT_INSIGHTS",
                                                        "CUSTOM"
                                                      ]
                                                    },
                                                    "evaluationCriteria": {
                                                      "description": "REQUIRED non-empty instruction telling the evaluator what to assess. One or two sentences in plain language: what to evaluate, and — when structuredDataParams is set — how to populate each declared field. Empty strings, null, or omission are forbidden; an empty description leaves the reasoning useless. Example: \"Decide whether the user is asking about real-estate availability. Set isAvailability to true only when the user is clearly asking whether a property is available; otherwise false.\"",
                                                      "type": "string"
                                                    },
                                                    "evaluationSteps": {
                                                      "type": "array",
                                                      "items": {
                                                        "type": "string"
                                                      }
                                                    },
                                                    "structuredDataParams": {
                                                      "anyOf": [
                                                        {
                                                          "type": "object",
                                                          "propertyNames": {
                                                            "type": "string"
                                                          },
                                                          "additionalProperties": {}
                                                        },
                                                        {
                                                          "type": "null"
                                                        }
                                                      ]
                                                    },
                                                    "metadata": {
                                                      "anyOf": [
                                                        {
                                                          "type": "object",
                                                          "propertyNames": {
                                                            "type": "string"
                                                          },
                                                          "additionalProperties": {}
                                                        },
                                                        {
                                                          "type": "null"
                                                        }
                                                      ]
                                                    },
                                                    "enabled": {
                                                      "type": "boolean"
                                                    },
                                                    "applicationId": {
                                                      "type": "number"
                                                    },
                                                    "evaluationParams": {
                                                      "type": "array",
                                                      "items": {
                                                        "type": "string",
                                                        "enum": [
                                                          "INPUT",
                                                          "ACTUAL_OUTPUT",
                                                          "EXPECTED_OUTPUT",
                                                          "CONTEXT",
                                                          "RETRIEVAL_CONTEXT",
                                                          "EXECUTION_CONTEXT"
                                                        ]
                                                      }
                                                    }
                                                  },
                                                  "required": [
                                                    "name",
                                                    "type",
                                                    "evaluationCriteria"
                                                  ],
                                                  "additionalProperties": false
                                                }
                                              ]
                                            }
                                          },
                                          "transition": {
                                            "description": "Transitions to other nodes based on evaluation results.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/exportAgent_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ],
                                                  "additionalProperties": false
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ],
                                              "additionalProperties": false
                                            }
                                          },
                                          "cachePolicy": {
                                            "description": "Controls execution caching for this decision node across messages in a conversation. auto (default): cache result and use a lightweight guard evaluation to detect staleness. always: always use cached result until explicitly cleared. never: always re-evaluate all criteria every message (disables caching).",
                                            "type": "string",
                                            "enum": [
                                              "auto",
                                              "always",
                                              "never"
                                            ]
                                          },
                                          "selectionPolicy": {
                                            "description": "Controls which enabled criteria are evaluated each message. all (default): every enabled criterion runs. contextual: a lightweight router selects only the criteria relevant to the current input and conversation state; the rest are skipped. Skipped criteria are not evaluated, so their structuredData fields are absent downstream (route on them with the \"exists\"/\"notExists\" operators) and scores.mean reflects only the criteria that ran.",
                                            "type": "string",
                                            "enum": [
                                              "all",
                                              "contextual"
                                            ]
                                          },
                                          "alwaysRunCriteria": {
                                            "description": "Only used when selectionPolicy is \"contextual\": IDs of evaluation criteria that always run (they bypass the router); every other criterion is AI-selected per message. Use this to pin extractors whose structuredData a downstream node depends on. Ignored when selectionPolicy is \"all\".",
                                            "type": "array",
                                            "items": {
                                              "type": "string"
                                            }
                                          },
                                          "contextualSelectionPrompt": {
                                            "description": "Only used when selectionPolicy is \"contextual\": extra author guidance appended to the built-in router prompt to steer which criteria it picks (e.g. \"prefer running Consultar NFSe whenever the user mentions a nota fiscal, even indirectly\"). It augments the router — it does not replace its output contract or the safe fallback of running everything. Ignored when selectionPolicy is \"all\".",
                                            "type": "string"
                                          },
                                          "routingPolicy": {
                                            "description": "How many REASONINGS (criteria) may win the routing on this node per message. all (default): every matching conditional transition fires in parallel. bestReasoning: only the highest-scoring reasoning wins — ALL matched transitions whose condition is anchored on it fire (they are that reasoning's flow), everything anchored on other reasonings is suppressed. topReasonings: like bestReasoning but the best `maxReasonings` reasonings win. A matched transition is anchored on the highest-scoring criterion its condition references (via \"resultsById.<id>.score\" paths, at any nesting). Score ties between reasonings break by position in this node's evaluationCriteria list (earlier wins) — reorder the list to set priority. Matched transitions that reference NO criterion score (pure structuredData/context/state conditions) are outside the competition and always fire, like \"default\" and unconditional transitions. Criteria evaluation is unaffected — this arbitrates AFTER scoring, so it is the reliable way to get \"only one reasoning wins\" (independent per-criterion evaluations cannot be prompted into exclusivity).",
                                            "type": "string",
                                            "enum": [
                                              "all",
                                              "bestReasoning",
                                              "topReasonings"
                                            ]
                                          },
                                          "maxReasonings": {
                                            "description": "Only used when routingPolicy is \"topReasonings\": how many of the highest-scoring reasonings win the routing. Ignored for other policies (\"bestReasoning\" is exactly maxReasonings = 1).",
                                            "type": "integer",
                                            "minimum": 1,
                                            "maximum": 9007199254740991
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type",
                                          "evaluationCriteria",
                                          "transition"
                                        ],
                                        "additionalProperties": false
                                      },
                                      {
                                        "oneOf": [
                                          {
                                            "type": "object",
                                            "properties": {
                                              "id": {
                                                "description": "Unique identifier for this node.",
                                                "type": "string"
                                              },
                                              "type": {
                                                "type": "string",
                                                "const": "action"
                                              },
                                              "label": {
                                                "description": "Human-readable label for this action node.",
                                                "type": "string"
                                              },
                                              "mode": {
                                                "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                "type": "string",
                                                "enum": [
                                                  "sync",
                                                  "async"
                                                ]
                                              },
                                              "outputVar": {
                                                "description": "Variable name to store the action output for use by downstream nodes.",
                                                "type": "string"
                                              },
                                              "transition": {
                                                "description": "Transitions to other nodes after this action completes.",
                                                "type": "array",
                                                "items": {
                                                  "type": "object",
                                                  "properties": {
                                                    "if": {
                                                      "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                      "$ref": "#/components/schemas/exportAgent_schema0"
                                                    },
                                                    "default": {
                                                      "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                      "type": "boolean"
                                                    },
                                                    "to": {
                                                      "type": "object",
                                                      "properties": {
                                                        "nodeId": {
                                                          "description": "The ID of the target node to transition to.",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "required": [
                                                        "nodeId"
                                                      ],
                                                      "additionalProperties": false
                                                    },
                                                    "stop": {
                                                      "description": "If true, stop execution after this transition.",
                                                      "type": "boolean"
                                                    }
                                                  },
                                                  "required": [
                                                    "to"
                                                  ],
                                                  "additionalProperties": false
                                                }
                                              },
                                              "actionType": {
                                                "type": "string",
                                                "const": "INSTRUCTIONS"
                                              },
                                              "config": {
                                                "type": "object",
                                                "properties": {
                                                  "instructions": {
                                                    "description": "The instructions for the LLM to execute.",
                                                    "type": "string"
                                                  },
                                                  "modelTier": {
                                                    "description": "The model tier to use for this instruction. Defaults to regular.",
                                                    "type": "string",
                                                    "enum": [
                                                      "lite",
                                                      "regular",
                                                      "pro"
                                                    ]
                                                  },
                                                  "thinkingEffortPct": {
                                                    "description": "Thinking effort percentage (0-100) controlling how much reasoning the model applies.",
                                                    "type": "number",
                                                    "minimum": 0,
                                                    "maximum": 100
                                                  },
                                                  "maxOutputTokens": {
                                                    "description": "Maximum tokens the model may generate for this node. On thinking models the budget is SHARED between reasoning and output — reasoning routinely consumes most of it — so a node whose structured output is truncated is usually better served by lowering thinkingEffortPct than by raising this. Defaults to the model maximum when omitted.",
                                                    "type": "integer",
                                                    "minimum": 1,
                                                    "maximum": 9007199254740991
                                                  },
                                                  "maxRetries": {
                                                    "description": "How many times this node retries a failed model call. Defaults to 2 when the node has an outputSchema and 5 otherwise. Raise it for nodes whose long outputs are exposed to dropped provider streams; it does not help failures the model reproduces deterministically.",
                                                    "type": "integer",
                                                    "minimum": 1,
                                                    "maximum": 10
                                                  },
                                                  "toolChoiceMode": {
                                                    "description": "Tool selection mode for this instruction. Defaults to auto when omitted.",
                                                    "type": "string",
                                                    "enum": [
                                                      "auto",
                                                      "none",
                                                      "tool",
                                                      "tools"
                                                    ]
                                                  },
                                                  "toolChoiceToolName": {
                                                    "description": "When toolChoiceMode is \"tool\", the specific tool name to force.",
                                                    "type": "string"
                                                  },
                                                  "toolChoiceToolNames": {
                                                    "description": "When toolChoiceMode is \"tools\", the list of allowed tool names.",
                                                    "type": "array",
                                                    "items": {
                                                      "type": "string"
                                                    }
                                                  },
                                                  "suppressTextResponse": {
                                                    "description": "When true, text output from the LLM is suppressed and only tool-call results are emitted. Useful when the instruction should only invoke tools (e.g., displayMedia) without generating follow-up text.",
                                                    "type": "boolean"
                                                  },
                                                  "stopAfterFirstToolCall": {
                                                    "description": "When true and a single tool is forced with text suppressed, the instruction stops after the first successful tool call. Defaults to false, which allows the tool to be called across multiple steps.",
                                                    "type": "boolean"
                                                  },
                                                  "internal": {
                                                    "description": "When true, this node is an intermediate step: its text/structured output is NOT shown to the user (not streamed, not persisted as a visible message part) and is only captured into the node's outputVar for downstream nodes. Reasoning and tool-call activity chips remain visible. Use for internal hand-offs (e.g. tool-driven data synthesis a later node consumes); the user-facing reply should come from a later, non-internal node.",
                                                    "type": "boolean"
                                                  },
                                                  "outputSchema": {
                                                    "description": "JSON Schema for structured output. When provided, the LLM will output valid JSON matching this schema instead of free-form text.",
                                                    "type": "object",
                                                    "properties": {
                                                      "type": {
                                                        "description": "JSON Schema type, must be \"object\" for structured output.",
                                                        "type": "string",
                                                        "const": "object"
                                                      },
                                                      "properties": {
                                                        "description": "Schema properties defining the expected output structure.",
                                                        "type": "object",
                                                        "propertyNames": {
                                                          "type": "string"
                                                        },
                                                        "additionalProperties": {}
                                                      },
                                                      "required": {
                                                        "description": "Array of required property names.",
                                                        "type": "array",
                                                        "items": {
                                                          "type": "string"
                                                        }
                                                      },
                                                      "additionalProperties": {
                                                        "description": "Whether to allow additional properties not defined in the schema.",
                                                        "type": "boolean"
                                                      },
                                                      "description": {
                                                        "description": "Description of the expected output to guide the LLM.",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "type",
                                                      "properties"
                                                    ],
                                                    "additionalProperties": false
                                                  },
                                                  "grounding": {
                                                    "description": "Model-side grounding for this node. Only Google Search is available today.",
                                                    "type": "object",
                                                    "properties": {
                                                      "googleSearch": {
                                                        "description": "Enable Google Search grounding: the model searches the public web (via Gemini's built-in google_search tool) while executing this instruction and answers from what it finds. Set `{}` to enable with defaults. The node result then carries `grounding` — the queries Google ran and the sources it cited, each with the resolved article URL, its domain and the passages of the reply it supports — readable downstream as `nodes.<nodeId>.grounding` in javascript nodes and templates; the text/JSON reply itself still flows through outputVar as usual. With an outputSchema the search runs first and the JSON is synthesized afterwards with the numbered source list, so declare a `sourceIds` or `url` field if you want citations inside the structured output. Incompatible with toolChoiceMode \"tool\" and with suppressTextResponse (a forced tool call and Google Search in one request returns an empty reply); with toolChoiceMode \"none\" the node still searches but calls no other tool. Each prompt costs Google one search query per query the model decides to run (usually 4–10), billed per query beyond the project's free tier.",
                                                        "type": "object",
                                                        "properties": {
                                                          "excludeDomains": {
                                                            "description": "Domains Google Search must not ground on, e.g. [\"youtube.com\", \"reddit.com\"]. A domain excludes its subdomains too.",
                                                            "type": "array",
                                                            "items": {
                                                              "type": "string"
                                                            }
                                                          }
                                                        },
                                                        "additionalProperties": false
                                                      }
                                                    },
                                                    "additionalProperties": false
                                                  },
                                                  "urlContext": {
                                                    "description": "Gemini URL context: hand the model a list of URLs to READ IN FULL server-side instead of fetching their text into a variable first. The URLs come from the fixed \"urls\" list, from the \"from\" value path, or from both (fixed first). They are appended to the end of the instruction and the provider fetches and reads the pages inside the same call. With an outputSchema the node runs as a SINGLE call (reading and synthesis must share it), so pair it with toolChoiceMode \"none\" unless the node truly needs function tools. Limits: 20 URLs per call (extra ones are dropped and reported as `truncated`), public pages only — paywalls, Google News redirect links and private hosts fail. The model may skip fetching when the URLs sit inside a very long prompt, so prefer a dedicated short reading node over bolting URLs onto a large synthesis prompt. The node output carries `urlContext.{requested,retrieved,unread,truncated,invalid,unresolved,supported,tokens}`. `unread` is the integrity signal — it lists every URL the model did not read, including the ones dropped by the 20-URL cap — so branch on `nodes.<id>.urlContext.unread` for a fallback reader (inside a forEach body it holds only the last item). `unresolved` says the \"from\" path resolved to nothing, `invalid` lists entries that were not http(s) URLs, and `supported` is false when the model could not carry the tool: in those cases nothing was read at all. Retrieved page content is billed as input tokens and added to the node usage as `urlContextTokens`. Gemini 3+ models only.",
                                                    "type": "object",
                                                    "properties": {
                                                      "urls": {
                                                        "description": "Fixed http(s) URLs to read on every run, written out here — for pages that do not change per execution (a status page, a policy, a price list). Combine with \"from\" to read a fixed set plus whatever the run produced; the two lists concatenate, fixed URLs first.",
                                                        "type": "array",
                                                        "items": {
                                                          "type": "string"
                                                        }
                                                      },
                                                      "from": {
                                                        "description": "Dotted VALUE PATH (same resolution as forEach \"over\": workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — e.g. \"paraLer.soUrls\" or \"nodes.pick.result.urls\") to a URL list the run produced: an array of http(s) URL strings, a single URL string, or a JSON-encoded array string. Not a Handlebars template; a path wrapped in {{ }} is accepted and unwrapped.",
                                                        "type": "string",
                                                        "minLength": 1
                                                      }
                                                    },
                                                    "additionalProperties": false
                                                  }
                                                },
                                                "required": [
                                                  "instructions"
                                                ],
                                                "additionalProperties": false
                                              }
                                            },
                                            "required": [
                                              "id",
                                              "type",
                                              "mode",
                                              "transition",
                                              "actionType",
                                              "config"
                                            ],
                                            "additionalProperties": false
                                          },
                                          {
                                            "type": "object",
                                            "properties": {
                                              "id": {
                                                "description": "Unique identifier for this node.",
                                                "type": "string"
                                              },
                                              "type": {
                                                "type": "string",
                                                "const": "action"
                                              },
                                              "label": {
                                                "description": "Human-readable label for this action node.",
                                                "type": "string"
                                              },
                                              "mode": {
                                                "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                "type": "string",
                                                "enum": [
                                                  "sync",
                                                  "async"
                                                ]
                                              },
                                              "outputVar": {
                                                "description": "Variable name to store the action output for use by downstream nodes.",
                                                "type": "string"
                                              },
                                              "transition": {
                                                "description": "Transitions to other nodes after this action completes.",
                                                "type": "array",
                                                "items": {
                                                  "type": "object",
                                                  "properties": {
                                                    "if": {
                                                      "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                      "$ref": "#/components/schemas/exportAgent_schema0"
                                                    },
                                                    "default": {
                                                      "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                      "type": "boolean"
                                                    },
                                                    "to": {
                                                      "type": "object",
                                                      "properties": {
                                                        "nodeId": {
                                                          "description": "The ID of the target node to transition to.",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "required": [
                                                        "nodeId"
                                                      ],
                                                      "additionalProperties": false
                                                    },
                                                    "stop": {
                                                      "description": "If true, stop execution after this transition.",
                                                      "type": "boolean"
                                                    }
                                                  },
                                                  "required": [
                                                    "to"
                                                  ],
                                                  "additionalProperties": false
                                                }
                                              },
                                              "actionType": {
                                                "type": "string",
                                                "const": "EMAIL"
                                              },
                                              "config": {
                                                "type": "object",
                                                "properties": {
                                                  "to": {
                                                    "type": "string"
                                                  },
                                                  "senderType": {
                                                    "type": "string",
                                                    "enum": [
                                                      "default",
                                                      "gmail"
                                                    ]
                                                  },
                                                  "gmailIntegrationId": {
                                                    "type": "string"
                                                  },
                                                  "subject": {
                                                    "type": "string"
                                                  },
                                                  "body": {
                                                    "type": "string"
                                                  },
                                                  "cc": {
                                                    "type": "string"
                                                  },
                                                  "bcc": {
                                                    "type": "string"
                                                  },
                                                  "attachments": {
                                                    "type": "array",
                                                    "items": {
                                                      "type": "object",
                                                      "properties": {
                                                        "documentId": {
                                                          "type": "number"
                                                        },
                                                        "url": {
                                                          "type": "string"
                                                        },
                                                        "filename": {
                                                          "type": "string"
                                                        }
                                                      },
                                                      "additionalProperties": false
                                                    }
                                                  },
                                                  "templateId": {
                                                    "type": "string"
                                                  },
                                                  "templateName": {
                                                    "type": "string"
                                                  },
                                                  "applicationId": {
                                                    "type": "number"
                                                  }
                                                },
                                                "required": [
                                                  "to",
                                                  "subject",
                                                  "body"
                                                ],
                                                "additionalProperties": false
                                              }
                                            },
                                            "required": [
                                              "id",
                                              "type",
                                              "mode",
                                              "transition",
                                              "actionType",
                                              "config"
                                            ],
                                            "additionalProperties": false
                                          },
                                          {
                                            "type": "object",
                                            "properties": {
                                              "id": {
                                                "description": "Unique identifier for this node.",
                                                "type": "string"
                                              },
                                              "type": {
                                                "type": "string",
                                                "const": "action"
                                              },
                                              "label": {
                                                "description": "Human-readable label for this action node.",
                                                "type": "string"
                                              },
                                              "mode": {
                                                "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                "type": "string",
                                                "enum": [
                                                  "sync",
                                                  "async"
                                                ]
                                              },
                                              "outputVar": {
                                                "description": "Variable name to store the action output for use by downstream nodes.",
                                                "type": "string"
                                              },
                                              "transition": {
                                                "description": "Transitions to other nodes after this action completes.",
                                                "type": "array",
                                                "items": {
                                                  "type": "object",
                                                  "properties": {
                                                    "if": {
                                                      "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                      "$ref": "#/components/schemas/exportAgent_schema0"
                                                    },
                                                    "default": {
                                                      "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                      "type": "boolean"
                                                    },
                                                    "to": {
                                                      "type": "object",
                                                      "properties": {
                                                        "nodeId": {
                                                          "description": "The ID of the target node to transition to.",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "required": [
                                                        "nodeId"
                                                      ],
                                                      "additionalProperties": false
                                                    },
                                                    "stop": {
                                                      "description": "If true, stop execution after this transition.",
                                                      "type": "boolean"
                                                    }
                                                  },
                                                  "required": [
                                                    "to"
                                                  ],
                                                  "additionalProperties": false
                                                }
                                              },
                                              "actionType": {
                                                "type": "string",
                                                "const": "WEBHOOK"
                                              },
                                              "config": {
                                                "type": "object",
                                                "properties": {
                                                  "url": {
                                                    "type": "string"
                                                  },
                                                  "method": {
                                                    "type": "string",
                                                    "enum": [
                                                      "GET",
                                                      "POST",
                                                      "PUT",
                                                      "PATCH",
                                                      "DELETE"
                                                    ]
                                                  },
                                                  "headers": {
                                                    "type": "object",
                                                    "propertyNames": {
                                                      "type": "string"
                                                    },
                                                    "additionalProperties": {
                                                      "type": "string"
                                                    }
                                                  },
                                                  "queryParams": {
                                                    "type": "object",
                                                    "propertyNames": {
                                                      "type": "string"
                                                    },
                                                    "additionalProperties": {
                                                      "type": "string"
                                                    }
                                                  },
                                                  "body": {
                                                    "type": "string"
                                                  },
                                                  "timeout": {
                                                    "type": "number"
                                                  },
                                                  "responseMode": {
                                                    "description": "How to decode the response body. \"json\" (default): parse as JSON/text and expose via varsDelta. \"attachment\": read as binary bytes for multimodal input (e.g. PDFs, images).",
                                                    "type": "string",
                                                    "enum": [
                                                      "json",
                                                      "attachment"
                                                    ]
                                                  },
                                                  "asMessage": {
                                                    "description": "When true, append the response to the conversation as a new user message so downstream LLM nodes see it. In \"attachment\" mode the message carries a file content part; in \"json\" mode it carries the stringified body as text. Defaults to false — preserving the historical behavior where webhook responses only flow through varsDelta.",
                                                    "type": "boolean"
                                                  },
                                                  "suppressNoResponseFallback": {
                                                    "description": "Marks the webhook as a fire-and-forget trigger: the conversation is meant to end here, with the rest happening on the receiving system. When the call succeeds and the turn finishes without sending anything to the user, the channel skips its automatic \"sorry, something went wrong\" fallback message. A failed call (HTTP >= 400) still gets the fallback, since the user is then left waiting for nothing.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "url",
                                                  "method"
                                                ],
                                                "additionalProperties": false
                                              }
                                            },
                                            "required": [
                                              "id",
                                              "type",
                                              "mode",
                                              "transition",
                                              "actionType",
                                              "config"
                                            ],
                                            "additionalProperties": false
                                          },
                                          {
                                            "type": "object",
                                            "properties": {
                                              "id": {
                                                "description": "Unique identifier for this node.",
                                                "type": "string"
                                              },
                                              "type": {
                                                "type": "string",
                                                "const": "action"
                                              },
                                              "label": {
                                                "description": "Human-readable label for this action node.",
                                                "type": "string"
                                              },
                                              "mode": {
                                                "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                "type": "string",
                                                "enum": [
                                                  "sync",
                                                  "async"
                                                ]
                                              },
                                              "outputVar": {
                                                "description": "Variable name to store the action output for use by downstream nodes.",
                                                "type": "string"
                                              },
                                              "transition": {
                                                "description": "Transitions to other nodes after this action completes.",
                                                "type": "array",
                                                "items": {
                                                  "type": "object",
                                                  "properties": {
                                                    "if": {
                                                      "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                      "$ref": "#/components/schemas/exportAgent_schema0"
                                                    },
                                                    "default": {
                                                      "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                      "type": "boolean"
                                                    },
                                                    "to": {
                                                      "type": "object",
                                                      "properties": {
                                                        "nodeId": {
                                                          "description": "The ID of the target node to transition to.",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "required": [
                                                        "nodeId"
                                                      ],
                                                      "additionalProperties": false
                                                    },
                                                    "stop": {
                                                      "description": "If true, stop execution after this transition.",
                                                      "type": "boolean"
                                                    }
                                                  },
                                                  "required": [
                                                    "to"
                                                  ],
                                                  "additionalProperties": false
                                                }
                                              },
                                              "actionType": {
                                                "type": "string",
                                                "const": "DOCUMENT_TEMPLATE"
                                              },
                                              "config": {
                                                "type": "object",
                                                "properties": {
                                                  "templateId": {
                                                    "type": "string"
                                                  },
                                                  "templateName": {
                                                    "type": "string"
                                                  },
                                                  "sendEmail": {
                                                    "type": "boolean"
                                                  },
                                                  "sendWhatsApp": {
                                                    "type": "boolean"
                                                  },
                                                  "recipientEmail": {
                                                    "type": "string"
                                                  }
                                                },
                                                "required": [
                                                  "templateId"
                                                ],
                                                "additionalProperties": false
                                              }
                                            },
                                            "required": [
                                              "id",
                                              "type",
                                              "mode",
                                              "transition",
                                              "actionType",
                                              "config"
                                            ],
                                            "additionalProperties": false
                                          },
                                          {
                                            "type": "object",
                                            "properties": {
                                              "id": {
                                                "description": "Unique identifier for this node.",
                                                "type": "string"
                                              },
                                              "type": {
                                                "type": "string",
                                                "const": "action"
                                              },
                                              "label": {
                                                "description": "Human-readable label for this action node.",
                                                "type": "string"
                                              },
                                              "mode": {
                                                "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                "type": "string",
                                                "enum": [
                                                  "sync",
                                                  "async"
                                                ]
                                              },
                                              "outputVar": {
                                                "description": "Variable name to store the action output for use by downstream nodes.",
                                                "type": "string"
                                              },
                                              "transition": {
                                                "description": "Transitions to other nodes after this action completes.",
                                                "type": "array",
                                                "items": {
                                                  "type": "object",
                                                  "properties": {
                                                    "if": {
                                                      "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                      "$ref": "#/components/schemas/exportAgent_schema0"
                                                    },
                                                    "default": {
                                                      "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                      "type": "boolean"
                                                    },
                                                    "to": {
                                                      "type": "object",
                                                      "properties": {
                                                        "nodeId": {
                                                          "description": "The ID of the target node to transition to.",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "required": [
                                                        "nodeId"
                                                      ],
                                                      "additionalProperties": false
                                                    },
                                                    "stop": {
                                                      "description": "If true, stop execution after this transition.",
                                                      "type": "boolean"
                                                    }
                                                  },
                                                  "required": [
                                                    "to"
                                                  ],
                                                  "additionalProperties": false
                                                }
                                              },
                                              "actionType": {
                                                "type": "string",
                                                "const": "TOOL_CALL"
                                              },
                                              "config": {
                                                "type": "object",
                                                "properties": {
                                                  "toolName": {
                                                    "description": "The name of the common tool to invoke.",
                                                    "type": "string"
                                                  },
                                                  "parameters": {
                                                    "description": "Per-parameter configuration. Keys are parameter names from the tool schema.",
                                                    "type": "object",
                                                    "propertyNames": {
                                                      "type": "string"
                                                    },
                                                    "additionalProperties": {
                                                      "type": "object",
                                                      "properties": {
                                                        "mode": {
                                                          "description": "Whether this parameter is hardcoded (static) or filled by the LLM at runtime (dynamic).",
                                                          "type": "string",
                                                          "enum": [
                                                            "static",
                                                            "dynamic"
                                                          ]
                                                        },
                                                        "staticValue": {
                                                          "description": "The fixed value for this parameter. Required when mode is \"static\"."
                                                        },
                                                        "instructions": {
                                                          "description": "Optional guidance for the LLM when filling this parameter (only used when mode is \"dynamic\").",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "required": [
                                                        "mode"
                                                      ],
                                                      "additionalProperties": false
                                                    }
                                                  },
                                                  "instructions": {
                                                    "description": "General instructions for the LLM when resolving dynamic parameters.",
                                                    "type": "string"
                                                  },
                                                  "skipKnowledgeSearch": {
                                                    "description": "When a node has dynamic parameters, the model is normally forced to call similaritySearch first so parameter values are grounded in the knowledge base, costing one extra model round. Set true for tools that need no knowledge context (for example code execution) to call the configured tool directly. Ignored when every parameter is static, since no model runs at all.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "toolName"
                                                ],
                                                "additionalProperties": false
                                              }
                                            },
                                            "required": [
                                              "id",
                                              "type",
                                              "mode",
                                              "transition",
                                              "actionType",
                                              "config"
                                            ],
                                            "additionalProperties": false
                                          },
                                          {
                                            "type": "object",
                                            "properties": {
                                              "id": {
                                                "description": "Unique identifier for this node.",
                                                "type": "string"
                                              },
                                              "type": {
                                                "type": "string",
                                                "const": "action"
                                              },
                                              "label": {
                                                "description": "Human-readable label for this action node.",
                                                "type": "string"
                                              },
                                              "mode": {
                                                "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                "type": "string",
                                                "enum": [
                                                  "sync",
                                                  "async"
                                                ]
                                              },
                                              "outputVar": {
                                                "description": "Variable name to store the action output for use by downstream nodes.",
                                                "type": "string"
                                              },
                                              "transition": {
                                                "description": "Transitions to other nodes after this action completes.",
                                                "type": "array",
                                                "items": {
                                                  "type": "object",
                                                  "properties": {
                                                    "if": {
                                                      "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                      "$ref": "#/components/schemas/exportAgent_schema0"
                                                    },
                                                    "default": {
                                                      "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                      "type": "boolean"
                                                    },
                                                    "to": {
                                                      "type": "object",
                                                      "properties": {
                                                        "nodeId": {
                                                          "description": "The ID of the target node to transition to.",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "required": [
                                                        "nodeId"
                                                      ],
                                                      "additionalProperties": false
                                                    },
                                                    "stop": {
                                                      "description": "If true, stop execution after this transition.",
                                                      "type": "boolean"
                                                    }
                                                  },
                                                  "required": [
                                                    "to"
                                                  ],
                                                  "additionalProperties": false
                                                }
                                              },
                                              "actionType": {
                                                "type": "string",
                                                "const": "FOLLOW_UP"
                                              },
                                              "config": {
                                                "type": "object",
                                                "properties": {
                                                  "delayMinutes": {
                                                    "description": "Minutes to wait before checking whether to run the inner action. Common presets: 5, 10, 15. Maximum 1440 (24h). Cloud Scheduler is cron-based so the actual fire time is rounded to the next minute boundary.",
                                                    "type": "integer",
                                                    "minimum": 1,
                                                    "maximum": 1440
                                                  },
                                                  "cancelOnUserMessage": {
                                                    "description": "When true (default), skip the inner action if any USER message arrived after the node was reached. Set to false only if the follow-up should fire even after the user has replied.",
                                                    "type": "boolean"
                                                  },
                                                  "cancelOnAssistantMessage": {
                                                    "description": "When true (default), skip the inner action if any ASSISTANT text message was sent after the node was reached. Tool-only assistant messages (no text content) do NOT count. Prevents double-pinging when another node already produced a response.",
                                                    "type": "boolean"
                                                  },
                                                  "cancelOnArchive": {
                                                    "description": "When true (default), skip the inner action if the thread was archived between scheduling and firing.",
                                                    "type": "boolean"
                                                  },
                                                  "action": {
                                                    "description": "The inner action to run when the delay elapses and cancel rules pass. INSTRUCTIONS produces an LLM-generated text message (good for \"Are you still there?\"-style nudges). TOOL_CALL fires a display tool (good for offering options or showing media).",
                                                    "oneOf": [
                                                      {
                                                        "type": "object",
                                                        "properties": {
                                                          "actionType": {
                                                            "type": "string",
                                                            "const": "INSTRUCTIONS"
                                                          },
                                                          "config": {
                                                            "type": "object",
                                                            "properties": {
                                                              "instructions": {
                                                                "description": "The instructions for the LLM to execute.",
                                                                "type": "string"
                                                              },
                                                              "modelTier": {
                                                                "description": "The model tier to use for this instruction. Defaults to regular.",
                                                                "type": "string",
                                                                "enum": [
                                                                  "lite",
                                                                  "regular",
                                                                  "pro"
                                                                ]
                                                              },
                                                              "thinkingEffortPct": {
                                                                "description": "Thinking effort percentage (0-100) controlling how much reasoning the model applies.",
                                                                "type": "number",
                                                                "minimum": 0,
                                                                "maximum": 100
                                                              },
                                                              "maxOutputTokens": {
                                                                "description": "Maximum tokens the model may generate for this node. On thinking models the budget is SHARED between reasoning and output — reasoning routinely consumes most of it — so a node whose structured output is truncated is usually better served by lowering thinkingEffortPct than by raising this. Defaults to the model maximum when omitted.",
                                                                "type": "integer",
                                                                "minimum": 1,
                                                                "maximum": 9007199254740991
                                                              },
                                                              "maxRetries": {
                                                                "description": "How many times this node retries a failed model call. Defaults to 2 when the node has an outputSchema and 5 otherwise. Raise it for nodes whose long outputs are exposed to dropped provider streams; it does not help failures the model reproduces deterministically.",
                                                                "type": "integer",
                                                                "minimum": 1,
                                                                "maximum": 10
                                                              },
                                                              "toolChoiceMode": {
                                                                "description": "Tool selection mode for this instruction. Defaults to auto when omitted.",
                                                                "type": "string",
                                                                "enum": [
                                                                  "auto",
                                                                  "none",
                                                                  "tool",
                                                                  "tools"
                                                                ]
                                                              },
                                                              "toolChoiceToolName": {
                                                                "description": "When toolChoiceMode is \"tool\", the specific tool name to force.",
                                                                "type": "string"
                                                              },
                                                              "toolChoiceToolNames": {
                                                                "description": "When toolChoiceMode is \"tools\", the list of allowed tool names.",
                                                                "type": "array",
                                                                "items": {
                                                                  "type": "string"
                                                                }
                                                              },
                                                              "suppressTextResponse": {
                                                                "description": "When true, text output from the LLM is suppressed and only tool-call results are emitted. Useful when the instruction should only invoke tools (e.g., displayMedia) without generating follow-up text.",
                                                                "type": "boolean"
                                                              },
                                                              "stopAfterFirstToolCall": {
                                                                "description": "When true and a single tool is forced with text suppressed, the instruction stops after the first successful tool call. Defaults to false, which allows the tool to be called across multiple steps.",
                                                                "type": "boolean"
                                                              },
                                                              "internal": {
                                                                "description": "When true, this node is an intermediate step: its text/structured output is NOT shown to the user (not streamed, not persisted as a visible message part) and is only captured into the node's outputVar for downstream nodes. Reasoning and tool-call activity chips remain visible. Use for internal hand-offs (e.g. tool-driven data synthesis a later node consumes); the user-facing reply should come from a later, non-internal node.",
                                                                "type": "boolean"
                                                              },
                                                              "outputSchema": {
                                                                "description": "JSON Schema for structured output. When provided, the LLM will output valid JSON matching this schema instead of free-form text.",
                                                                "type": "object",
                                                                "properties": {
                                                                  "type": {
                                                                    "description": "JSON Schema type, must be \"object\" for structured output.",
                                                                    "type": "string",
                                                                    "const": "object"
                                                                  },
                                                                  "properties": {
                                                                    "description": "Schema properties defining the expected output structure.",
                                                                    "type": "object",
                                                                    "propertyNames": {
                                                                      "type": "string"
                                                                    },
                                                                    "additionalProperties": {}
                                                                  },
                                                                  "required": {
                                                                    "description": "Array of required property names.",
                                                                    "type": "array",
                                                                    "items": {
                                                                      "type": "string"
                                                                    }
                                                                  },
                                                                  "additionalProperties": {
                                                                    "description": "Whether to allow additional properties not defined in the schema.",
                                                                    "type": "boolean"
                                                                  },
                                                                  "description": {
                                                                    "description": "Description of the expected output to guide the LLM.",
                                                                    "type": "string"
                                                                  }
                                                                },
                                                                "required": [
                                                                  "type",
                                                                  "properties"
                                                                ],
                                                                "additionalProperties": false
                                                              },
                                                              "grounding": {
                                                                "description": "Model-side grounding for this node. Only Google Search is available today.",
                                                                "type": "object",
                                                                "properties": {
                                                                  "googleSearch": {
                                                                    "description": "Enable Google Search grounding: the model searches the public web (via Gemini's built-in google_search tool) while executing this instruction and answers from what it finds. Set `{}` to enable with defaults. The node result then carries `grounding` — the queries Google ran and the sources it cited, each with the resolved article URL, its domain and the passages of the reply it supports — readable downstream as `nodes.<nodeId>.grounding` in javascript nodes and templates; the text/JSON reply itself still flows through outputVar as usual. With an outputSchema the search runs first and the JSON is synthesized afterwards with the numbered source list, so declare a `sourceIds` or `url` field if you want citations inside the structured output. Incompatible with toolChoiceMode \"tool\" and with suppressTextResponse (a forced tool call and Google Search in one request returns an empty reply); with toolChoiceMode \"none\" the node still searches but calls no other tool. Each prompt costs Google one search query per query the model decides to run (usually 4–10), billed per query beyond the project's free tier.",
                                                                    "type": "object",
                                                                    "properties": {
                                                                      "excludeDomains": {
                                                                        "description": "Domains Google Search must not ground on, e.g. [\"youtube.com\", \"reddit.com\"]. A domain excludes its subdomains too.",
                                                                        "type": "array",
                                                                        "items": {
                                                                          "type": "string"
                                                                        }
                                                                      }
                                                                    },
                                                                    "additionalProperties": false
                                                                  }
                                                                },
                                                                "additionalProperties": false
                                                              },
                                                              "urlContext": {
                                                                "description": "Gemini URL context: hand the model a list of URLs to READ IN FULL server-side instead of fetching their text into a variable first. The URLs come from the fixed \"urls\" list, from the \"from\" value path, or from both (fixed first). They are appended to the end of the instruction and the provider fetches and reads the pages inside the same call. With an outputSchema the node runs as a SINGLE call (reading and synthesis must share it), so pair it with toolChoiceMode \"none\" unless the node truly needs function tools. Limits: 20 URLs per call (extra ones are dropped and reported as `truncated`), public pages only — paywalls, Google News redirect links and private hosts fail. The model may skip fetching when the URLs sit inside a very long prompt, so prefer a dedicated short reading node over bolting URLs onto a large synthesis prompt. The node output carries `urlContext.{requested,retrieved,unread,truncated,invalid,unresolved,supported,tokens}`. `unread` is the integrity signal — it lists every URL the model did not read, including the ones dropped by the 20-URL cap — so branch on `nodes.<id>.urlContext.unread` for a fallback reader (inside a forEach body it holds only the last item). `unresolved` says the \"from\" path resolved to nothing, `invalid` lists entries that were not http(s) URLs, and `supported` is false when the model could not carry the tool: in those cases nothing was read at all. Retrieved page content is billed as input tokens and added to the node usage as `urlContextTokens`. Gemini 3+ models only.",
                                                                "type": "object",
                                                                "properties": {
                                                                  "urls": {
                                                                    "description": "Fixed http(s) URLs to read on every run, written out here — for pages that do not change per execution (a status page, a policy, a price list). Combine with \"from\" to read a fixed set plus whatever the run produced; the two lists concatenate, fixed URLs first.",
                                                                    "type": "array",
                                                                    "items": {
                                                                      "type": "string"
                                                                    }
                                                                  },
                                                                  "from": {
                                                                    "description": "Dotted VALUE PATH (same resolution as forEach \"over\": workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — e.g. \"paraLer.soUrls\" or \"nodes.pick.result.urls\") to a URL list the run produced: an array of http(s) URL strings, a single URL string, or a JSON-encoded array string. Not a Handlebars template; a path wrapped in {{ }} is accepted and unwrapped.",
                                                                    "type": "string",
                                                                    "minLength": 1
                                                                  }
                                                                },
                                                                "additionalProperties": false
                                                              }
                                                            },
                                                            "required": [
                                                              "instructions"
                                                            ],
                                                            "additionalProperties": false
                                                          }
                                                        },
                                                        "required": [
                                                          "actionType",
                                                          "config"
                                                        ],
                                                        "additionalProperties": false
                                                      },
                                                      {
                                                        "type": "object",
                                                        "properties": {
                                                          "actionType": {
                                                            "type": "string",
                                                            "const": "TOOL_CALL"
                                                          },
                                                          "config": {
                                                            "type": "object",
                                                            "properties": {
                                                              "toolName": {
                                                                "description": "The name of the common tool to invoke.",
                                                                "type": "string"
                                                              },
                                                              "parameters": {
                                                                "description": "Per-parameter configuration. Keys are parameter names from the tool schema.",
                                                                "type": "object",
                                                                "propertyNames": {
                                                                  "type": "string"
                                                                },
                                                                "additionalProperties": {
                                                                  "type": "object",
                                                                  "properties": {
                                                                    "mode": {
                                                                      "description": "Whether this parameter is hardcoded (static) or filled by the LLM at runtime (dynamic).",
                                                                      "type": "string",
                                                                      "enum": [
                                                                        "static",
                                                                        "dynamic"
                                                                      ]
                                                                    },
                                                                    "staticValue": {
                                                                      "description": "The fixed value for this parameter. Required when mode is \"static\"."
                                                                    },
                                                                    "instructions": {
                                                                      "description": "Optional guidance for the LLM when filling this parameter (only used when mode is \"dynamic\").",
                                                                      "type": "string"
                                                                    }
                                                                  },
                                                                  "required": [
                                                                    "mode"
                                                                  ],
                                                                  "additionalProperties": false
                                                                }
                                                              },
                                                              "instructions": {
                                                                "description": "General instructions for the LLM when resolving dynamic parameters.",
                                                                "type": "string"
                                                              },
                                                              "skipKnowledgeSearch": {
                                                                "description": "When a node has dynamic parameters, the model is normally forced to call similaritySearch first so parameter values are grounded in the knowledge base, costing one extra model round. Set true for tools that need no knowledge context (for example code execution) to call the configured tool directly. Ignored when every parameter is static, since no model runs at all.",
                                                                "type": "boolean"
                                                              }
                                                            },
                                                            "required": [
                                                              "toolName"
                                                            ],
                                                            "additionalProperties": false
                                                          }
                                                        },
                                                        "required": [
                                                          "actionType",
                                                          "config"
                                                        ],
                                                        "additionalProperties": false
                                                      }
                                                    ]
                                                  }
                                                },
                                                "required": [
                                                  "delayMinutes",
                                                  "action"
                                                ],
                                                "additionalProperties": false
                                              }
                                            },
                                            "required": [
                                              "id",
                                              "type",
                                              "mode",
                                              "transition",
                                              "actionType",
                                              "config"
                                            ],
                                            "additionalProperties": false
                                          }
                                        ]
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "subAgent"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this sub-agent node.",
                                            "type": "string"
                                          },
                                          "agentId": {
                                            "description": "The ID of the sub-agent to invoke.",
                                            "type": "string"
                                          },
                                          "instructions": {
                                            "description": "Optional instructions message prepended to the sub-agent conversation. Supports Handlebars interpolation against the parent execution scope: `{{var}}` reads workflow vars, `{{context.x}}` reads contextVars, `{{env.X}}` reads environment, `{{input.text}}` reads the original user input, and `{{nodes.<id>.<path>}}` reads prior node outputs.",
                                            "type": "string"
                                          },
                                          "transition": {
                                            "description": "Optional transitions to continue the flow after the sub-agent returns.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/exportAgent_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ],
                                                  "additionalProperties": false
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ],
                                              "additionalProperties": false
                                            }
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type",
                                          "agentId"
                                        ],
                                        "additionalProperties": false
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "end"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this end node.",
                                            "type": "string"
                                          },
                                          "config": {
                                            "description": "Optional configuration for the end node behavior.",
                                            "type": "object",
                                            "properties": {
                                              "resetConversationHistory": {
                                                "description": "If true, the next user message starts a new conversation with no prior history.",
                                                "type": "boolean"
                                              }
                                            },
                                            "additionalProperties": false
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type"
                                        ],
                                        "additionalProperties": false
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "state"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this state node.",
                                            "type": "string"
                                          },
                                          "outputVar": {
                                            "description": "Agent-scope get only: variable name that receives the value stored under `config.key` (null when the key has never been written). Downstream templates read it as `{{<outputVar>}}`; transition conditions as `{source:\"vars\", path:\"<outputVar>...\"}`.",
                                            "type": "string"
                                          },
                                          "config": {
                                            "type": "object",
                                            "properties": {
                                              "scope": {
                                                "description": "How long the data lives and who sees it. execution: this run only. session: this conversation (thread) — a NEW conversation starts empty. agent: durable memory shared by every execution of this agent, across conversations — use it to remember things between independent runs. Survives clearCache.",
                                                "type": "string",
                                                "enum": [
                                                  "execution",
                                                  "session",
                                                  "agent"
                                                ]
                                              },
                                              "operation": {
                                                "description": "Agent scope only (default set). set: durably store the `state` entries. get: read the entry under `key` into `outputVar`. Execution/session scopes are always set — their values are injected into templates automatically, so no get is needed.",
                                                "type": "string",
                                                "enum": [
                                                  "set",
                                                  "get"
                                                ]
                                              },
                                              "key": {
                                                "description": "Agent-scope get: the memory key to read. Supports Handlebars (e.g. \"evidence-{{context.cnpj}}\") so one node can address per-entity entries. Rendered keys are limited to 512 characters.",
                                                "type": "string"
                                              },
                                              "state": {
                                                "description": "Key-value pairs to set (required for set operations). String values support Handlebars. In agent scope the KEYS are templates too (e.g. \"evidence-{{context.cnpj}}\"), each entry is stored as its own durable row, and serialized values are size-capped.",
                                                "type": "object",
                                                "propertyNames": {
                                                  "type": "string"
                                                },
                                                "additionalProperties": {}
                                              }
                                            },
                                            "required": [
                                              "scope"
                                            ],
                                            "additionalProperties": false
                                          },
                                          "transition": {
                                            "description": "Optional transitions to continue the flow after setting state.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/exportAgent_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ],
                                                  "additionalProperties": false
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ],
                                              "additionalProperties": false
                                            }
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type",
                                          "config"
                                        ],
                                        "additionalProperties": false
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "hub"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this hub node.",
                                            "type": "string"
                                          },
                                          "transition": {
                                            "description": "Transitions to route connections to other nodes.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/exportAgent_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ],
                                                  "additionalProperties": false
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ],
                                              "additionalProperties": false
                                            }
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type"
                                        ],
                                        "additionalProperties": false
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "jump"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this jump node.",
                                            "type": "string"
                                          },
                                          "transition": {
                                            "description": "Target node to jump to unconditionally.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/exportAgent_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ],
                                                  "additionalProperties": false
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ],
                                              "additionalProperties": false
                                            }
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type"
                                        ],
                                        "additionalProperties": false
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "clearCache"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this clear cache node.",
                                            "type": "string"
                                          },
                                          "config": {
                                            "description": "Optional configuration controlling what is cleared.",
                                            "type": "object",
                                            "properties": {
                                              "clearScope": {
                                                "description": "What to clear. executionCache (default): clears only the decision result cache. all: clears the entire session state including user-defined session variables.",
                                                "type": "string",
                                                "enum": [
                                                  "executionCache",
                                                  "all"
                                                ]
                                              }
                                            },
                                            "additionalProperties": false
                                          },
                                          "transition": {
                                            "description": "Optional transitions to continue the flow after clearing cache.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/exportAgent_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ],
                                                  "additionalProperties": false
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ],
                                              "additionalProperties": false
                                            }
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type"
                                        ],
                                        "additionalProperties": false
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "javascript"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this JavaScript node.",
                                            "type": "string"
                                          },
                                          "outputVar": {
                                            "description": "Variable name to store the returned value for downstream nodes. Downstream templates read it as `{{<outputVar>}}`; transition conditions as `{source:\"vars\", path:\"<outputVar>...\"}`.",
                                            "type": "string"
                                          },
                                          "config": {
                                            "type": "object",
                                            "properties": {
                                              "code": {
                                                "description": "JavaScript source executed in a sandboxed QuickJS interpreter. Written as a function body: it receives ({ vars, evaluation, context, env, input, nodes }) and must `return` a JSON-serializable value. Synchronous only — no network, filesystem, require/import, or timers.",
                                                "type": "string"
                                              },
                                              "timeoutMs": {
                                                "description": "CPU deadline in milliseconds. Default 1000, max 10000.",
                                                "type": "integer",
                                                "minimum": 1,
                                                "maximum": 10000
                                              }
                                            },
                                            "required": [
                                              "code"
                                            ],
                                            "additionalProperties": false
                                          },
                                          "transition": {
                                            "description": "Optional transitions to continue the flow after the code runs.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/exportAgent_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ],
                                                  "additionalProperties": false
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ],
                                              "additionalProperties": false
                                            }
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type",
                                          "config"
                                        ],
                                        "additionalProperties": false
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "description": "Unique identifier for this node.",
                                            "type": "string"
                                          },
                                          "type": {
                                            "type": "string",
                                            "const": "forEach"
                                          },
                                          "label": {
                                            "description": "Human-readable label for this forEach node.",
                                            "type": "string"
                                          },
                                          "over": {
                                            "description": "Dotted path to the array to iterate, resolved against the execution scope: top-level workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — for example \"research.socioAlvos\" or \"nodes.build_plan.result.targets\". This is a VALUE PATH, not a Handlebars template: Handlebars renders to a string, so an array passed through it would arrive as \"[object Object]\". A path wrapped in {{ }} is accepted and unwrapped. If the path does not resolve to an array the node fails loudly instead of iterating a string.",
                                            "type": "string"
                                          },
                                          "as": {
                                            "description": "Variable name bound to the current element inside the body node: \"socio\" makes {{socio.nome}} available to the body's templates. Must not be \"iteration\", which is reserved for the {index, total} binding also exposed to the body.",
                                            "type": "string"
                                          },
                                          "each": {
                                            "description": "The body node, referenced by ID. Must be an action, javascript or subAgent node declared in workflow.nodes with no other incoming transitions, and must not be an entry point. Its own \"transition\" array is ignored — the forEach node owns what happens after every item finishes. decision nodes are rejected because the execution cache is keyed by node ID, so parallel instances would contend for one cache entry.",
                                            "type": "object",
                                            "properties": {
                                              "nodeId": {
                                                "description": "The ID of the node to run once per item.",
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "nodeId"
                                            ],
                                            "additionalProperties": false
                                          },
                                          "collectInto": {
                                            "description": "Variable name receiving the per-item results array. Each entry is {index, item, ok, value?, grounding?, error?, errorName?}, where \"value\" is whatever the body node's own outputVar would have held (undefined when the body declares none) and \"grounding\" is that item's Google Search queries and sources when the body is a grounded INSTRUCTIONS node — the same shape a standalone node exposes as nodes.<id>.grounding. Entries stay aligned with the source array by index, including failed items, so a downstream node can tell \"this item returned nothing\" apart from \"this item was never tried\". Omit only if nothing downstream needs the results.",
                                            "type": "string"
                                          },
                                          "maxConcurrency": {
                                            "description": "How many items run at once. Defaults to 5. Raise carefully: per-item parallelism hits provider rate limits well before it hits platform limits.",
                                            "type": "integer",
                                            "minimum": 1,
                                            "maximum": 20
                                          },
                                          "transition": {
                                            "description": "Transitions to continue the flow after every item has finished.",
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "if": {
                                                  "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                  "$ref": "#/components/schemas/exportAgent_schema0"
                                                },
                                                "default": {
                                                  "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                  "type": "boolean"
                                                },
                                                "to": {
                                                  "type": "object",
                                                  "properties": {
                                                    "nodeId": {
                                                      "description": "The ID of the target node to transition to.",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "nodeId"
                                                  ],
                                                  "additionalProperties": false
                                                },
                                                "stop": {
                                                  "description": "If true, stop execution after this transition.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "required": [
                                                "to"
                                              ],
                                              "additionalProperties": false
                                            }
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "type",
                                          "over",
                                          "as",
                                          "each"
                                        ],
                                        "additionalProperties": false
                                      }
                                    ]
                                  }
                                }
                              },
                              "required": [
                                "toolName",
                                "toolDescription",
                                "entryPoints",
                                "nodes"
                              ],
                              "additionalProperties": false
                            },
                            "tools": {
                              "deprecated": true,
                              "description": "Deprecated and ignored. Tool availability is configured by the application, not the agent spec.",
                              "type": "array",
                              "items": {}
                            },
                            "metadata": {
                              "description": "Arbitrary metadata for custom extensions. Not used by the execution engine.",
                              "type": "object",
                              "propertyNames": {
                                "type": "string"
                              },
                              "additionalProperties": {}
                            }
                          },
                          "required": [
                            "version",
                            "name",
                            "prompt",
                            "workflow"
                          ],
                          "additionalProperties": false
                        },
                        "evals": {
                          "description": "The evaluation test cases exported with the agent.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string",
                                "minLength": 1
                              },
                              "description": {
                                "anyOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "scheduler": {
                                "anyOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "evalSpec": {},
                              "enabled": {
                                "type": "boolean"
                              },
                              "selfImproveEnabled": {
                                "type": "boolean"
                              },
                              "selfImproveTargetScore": {
                                "anyOf": [
                                  {
                                    "type": "number"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "selfImproveMaxIterations": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991
                              },
                              "folderPath": {
                                "description": "Materialized '/'-separated folder path of the eval (e.g. 'Regressão/Checkout'), or null for root.",
                                "anyOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "tags": {
                                "description": "Free-form labels of the eval.",
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "metadata": {
                                "description": "Free-form data of the eval, including the `sources` conversations it was built from.",
                                "anyOf": [
                                  {
                                    "description": "Free-form data recorded on the eval. Provenance belongs under `sources`, a list whose entries have documented keys so every writer points at the originating conversations the same way. An eval drawn from a single conversation carries a one-element list.",
                                    "type": "object",
                                    "properties": {
                                      "sources": {
                                        "description": "The conversations the eval was built from, most relevant first.",
                                        "maxItems": 25,
                                        "type": "array",
                                        "items": {
                                          "type": "object",
                                          "properties": {
                                            "threadId": {
                                              "description": "Id of the thread the eval was built from.",
                                              "examples": [
                                                "cmc3k5r2b0004l608w1t8fmz9"
                                              ],
                                              "type": "string",
                                              "minLength": 1,
                                              "maxLength": 255
                                            },
                                            "executionId": {
                                              "description": "Id of the agent execution the eval was built from.",
                                              "examples": [
                                                "exec_01j9z3k2b4c5"
                                              ],
                                              "type": "string",
                                              "minLength": 1,
                                              "maxLength": 255
                                            },
                                            "messageId": {
                                              "description": "Id of the specific message the eval was built from.",
                                              "examples": [
                                                "cmc3k9p7f0007"
                                              ],
                                              "type": "string",
                                              "minLength": 1,
                                              "maxLength": 255
                                            },
                                            "url": {
                                              "description": "Link to the source conversation. Must be an absolute http(s) URL.",
                                              "examples": [
                                                "https://platform.docana.com/application/42/agents/a1/logs?search=thread-1"
                                              ],
                                              "type": "string",
                                              "minLength": 1,
                                              "maxLength": 2048
                                            },
                                            "label": {
                                              "description": "Human friendly name of the source conversation.",
                                              "examples": [
                                                "WhatsApp 5511 — 12/08"
                                              ],
                                              "type": "string",
                                              "minLength": 1,
                                              "maxLength": 255
                                            },
                                            "capturedAt": {
                                              "description": "ISO 8601 timestamp of when the eval was captured.",
                                              "examples": [
                                                "2026-08-17T12:00:00.000Z"
                                              ],
                                              "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))$"
                                            }
                                          },
                                          "additionalProperties": {}
                                        }
                                      }
                                    },
                                    "additionalProperties": {}
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              }
                            },
                            "required": [
                              "name",
                              "evalSpec"
                            ],
                            "additionalProperties": false
                          }
                        },
                        "routines": {
                          "description": "The routines exported with the agent, including their triggers. API trigger tokens are never exported.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string",
                                "minLength": 1
                              },
                              "prompt": {
                                "type": "string"
                              },
                              "enabled": {
                                "default": true,
                                "type": "boolean"
                              },
                              "metadata": {
                                "anyOf": [
                                  {
                                    "type": "object",
                                    "propertyNames": {
                                      "type": "string"
                                    },
                                    "additionalProperties": {}
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "triggers": {
                                "default": [],
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "type": {
                                      "type": "string",
                                      "enum": [
                                        "SCHEDULED",
                                        "API",
                                        "DOCUMENT_EVENT"
                                      ]
                                    },
                                    "enabled": {
                                      "default": true,
                                      "type": "boolean"
                                    },
                                    "cronExpression": {
                                      "anyOf": [
                                        {
                                          "type": "string"
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    },
                                    "collectionIds": {
                                      "default": [],
                                      "type": "array",
                                      "items": {
                                        "type": "integer",
                                        "minimum": -9007199254740991,
                                        "maximum": 9007199254740991
                                      }
                                    },
                                    "eventName": {
                                      "anyOf": [
                                        {
                                          "type": "string"
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    },
                                    "metadata": {
                                      "type": "object",
                                      "propertyNames": {
                                        "type": "string"
                                      },
                                      "additionalProperties": {}
                                    }
                                  },
                                  "required": [
                                    "type",
                                    "enabled",
                                    "collectionIds"
                                  ],
                                  "additionalProperties": false
                                }
                              }
                            },
                            "required": [
                              "name",
                              "prompt",
                              "enabled",
                              "triggers"
                            ],
                            "additionalProperties": false
                          }
                        },
                        "insights": {
                          "description": "Per-agent Conversation Insights config. On import, `null` clears the config on the target agent and an absent field leaves it untouched.",
                          "anyOf": [
                            {
                              "type": "object",
                              "properties": {
                                "enabled": {
                                  "description": "Master kill switch for this agent's insights. When false, no extraction runs anywhere (the post-execution hook is suppressed and the archive API rejects summarize=true) and no prior insights are injected into new conversations.",
                                  "type": "boolean"
                                },
                                "shareWithPastConversations": {
                                  "description": "When true (and `enabled` is true), inject summaries from this user's past archived conversations in the same application into LLM calls that consume conversation history (instruction nodes; decision criteria with EvaluationParams.CONTEXT). Defaults to false.",
                                  "type": "boolean"
                                },
                                "summaryMode": {
                                  "description": "When to extract insights for this agent. \"afterExecution\" (default) runs archive + extraction after every successful agent turn (with or without an End node), so channels like WhatsApp keep producing insights. \"onArchive\" skips the automatic hook; insights are only extracted when the archive API is called with summarize=true.",
                                  "type": "string",
                                  "enum": [
                                    "afterExecution",
                                    "onArchive"
                                  ]
                                },
                                "summaryConfig": {
                                  "description": "Config used when this agent extracts a new summary (End-node generateInsights or archive API with summarize=true).",
                                  "type": "object",
                                  "properties": {
                                    "summaryLength": {
                                      "description": "Target length of the generated summary.",
                                      "type": "string",
                                      "enum": [
                                        "short",
                                        "medium",
                                        "detailed"
                                      ]
                                    },
                                    "customPrompt": {
                                      "description": "Optional extra guidance appended to the summarizer system prompt.",
                                      "type": "string"
                                    },
                                    "historyMessageLimit": {
                                      "description": "Cap on the number of recent messages included when generating the summary. Omitted = no cap.",
                                      "type": "integer",
                                      "exclusiveMinimum": 0,
                                      "maximum": 9007199254740991
                                    },
                                    "maxSummaryChars": {
                                      "description": "Optional cap on the persisted summary length (characters).",
                                      "type": "integer",
                                      "exclusiveMinimum": 0,
                                      "maximum": 9007199254740991
                                    }
                                  },
                                  "additionalProperties": false
                                },
                                "frequency": {
                                  "description": "How often insights are extracted. \"onEnd\" (default) extracts once when the conversation is archived. \"everyTurn\" extracts after every message — the legacy behaviour, which costs roughly O(N^2) tokens over an N-turn conversation. When absent, the legacy `summaryMode` is used: \"afterExecution\" maps to \"everyTurn\", anything else maps to \"onEnd\". Any other stored value (e.g. a removed legacy mode) resolves to \"onEnd\", the cheap option.",
                                  "type": "string",
                                  "enum": [
                                    "onEnd",
                                    "everyTurn"
                                  ]
                                },
                                "samplingRate": {
                                  "description": "Share of conversations that produce insights automatically, 0..1. Defaults to 1 (all). The decision is a deterministic hash of (agentId, threadId), so a conversation is either sampled for its whole life or not at all. Explicit archive calls and on-demand generation always run regardless of this rate.",
                                  "type": "number",
                                  "minimum": 0,
                                  "maximum": 1
                                },
                                "dataPoints": {
                                  "description": "Structured data points to extract from the conversation when generating insights.",
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "id": {
                                        "description": "Stable identifier for the data point; reused across saves so snapshot history and aggregations stay correlated over time.",
                                        "type": "string"
                                      },
                                      "name": {
                                        "description": "Human-readable name of the data point (displayed in the UI).",
                                        "type": "string"
                                      },
                                      "description": {
                                        "description": "Instruction describing what this data point should capture from the conversation.",
                                        "type": "string"
                                      },
                                      "type": {
                                        "description": "The expected type of the extracted value.",
                                        "type": "string",
                                        "enum": [
                                          "string",
                                          "number",
                                          "boolean"
                                        ]
                                      }
                                    },
                                    "required": [
                                      "id",
                                      "name",
                                      "description",
                                      "type"
                                    ],
                                    "additionalProperties": false
                                  }
                                }
                              },
                              "required": [
                                "enabled"
                              ],
                              "additionalProperties": false
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "spec",
                        "evals",
                        "routines"
                      ],
                      "additionalProperties": {}
                    },
                    "subAgents": {
                      "description": "Every sub-agent the root agent references through its workflow, collected recursively.",
                      "type": "array",
                      "items": {
                        "description": "One agent inside an export bundle.",
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "Id of the agent in the source environment. On import it is used to find an existing agent to update and to remap sub-agent references.",
                            "examples": [
                              "cmc4v8xq10001l708h2vxk9d3"
                            ],
                            "type": "string"
                          },
                          "name": {
                            "description": "The agent's display name.",
                            "type": "string"
                          },
                          "description": {
                            "description": "The agent's description.",
                            "type": "string"
                          },
                          "spec": {
                            "description": "The agent's AgentSpecV2 workflow spec, with referenced evaluation criteria inlined for portability.",
                            "type": "object",
                            "properties": {
                              "version": {
                                "description": "Schema version. Must be \"2.0\".",
                                "type": "string",
                                "const": "2.0"
                              },
                              "id": {
                                "description": "Unique identifier for this agent. Auto-generated if not provided.",
                                "type": "string"
                              },
                              "name": {
                                "description": "Human-readable name of the agent.",
                                "type": "string"
                              },
                              "prompt": {
                                "description": "System instructions for the agent. Can be a single string or an array of strings joined at runtime.",
                                "anyOf": [
                                  {
                                    "type": "string",
                                    "minLength": 1
                                  },
                                  {
                                    "minItems": 1,
                                    "type": "array",
                                    "items": {
                                      "type": "string",
                                      "minLength": 1
                                    }
                                  }
                                ]
                              },
                              "llm": {
                                "description": "LLM configuration for the router persona. Optional; uses platform defaults when omitted.",
                                "type": "object",
                                "properties": {
                                  "provider": {
                                    "description": "The LLM provider identifier (e.g., \"google\", \"openai\").",
                                    "type": "string"
                                  },
                                  "model": {
                                    "description": "The model name to use (e.g., \"gemini-2.0-flash\").",
                                    "type": "string"
                                  },
                                  "temperature": {
                                    "description": "Sampling temperature (0-2). IGNORED on Gemini 3.x models, which Google deprecated this parameter for on 2026-07-21 — it is accepted and silently discarded, so it no longer makes output more deterministic. Still accepted for older models and for backwards compatibility with existing specs.",
                                    "type": "number"
                                  },
                                  "maxOutputTokens": {
                                    "description": "Maximum number of tokens the model can generate.",
                                    "type": "number"
                                  },
                                  "toolChoice": {
                                    "description": "Controls how the model uses tools: auto (model decides), required (must use a tool), none (no tools).",
                                    "type": "string",
                                    "enum": [
                                      "auto",
                                      "required",
                                      "none"
                                    ]
                                  },
                                  "jsonMode": {
                                    "description": "If true, the model outputs valid JSON.",
                                    "type": "boolean"
                                  }
                                },
                                "required": [
                                  "provider",
                                  "model"
                                ],
                                "additionalProperties": false
                              },
                              "inlineEvaluationCriteria": {
                                "description": "Map of criteria ID to its full definition. Decision nodes reference these by key. These are criteria that have not been persisted to the database yet. During sandbox execution, they are loaded into memory. During publish, they are persisted to the database and this field is cleared.",
                                "type": "object",
                                "propertyNames": {
                                  "type": "string"
                                },
                                "additionalProperties": {
                                  "type": "object",
                                  "properties": {
                                    "name": {
                                      "description": "Human-readable name of this evaluation criteria. MUST be a non-empty short noun phrase (e.g. \"Real-Estate Availability Intent\"). Empty strings are forbidden.",
                                      "type": "string"
                                    },
                                    "type": {
                                      "description": "The evaluation criteria type (e.g., CUSTOM, QUALITY_HELPFULNESS).",
                                      "type": "string",
                                      "enum": [
                                        "QUALITY_ENGAGINGNESS",
                                        "QUALITY_COHERENCE",
                                        "QUALITY_CONSISTENCY",
                                        "QUALITY_FLUENCY",
                                        "QUALITY_RELEVANCE",
                                        "SECURITY_FINANCIAL_DETECTION",
                                        "SECURITY_PII_DETECTION",
                                        "SECURITY_ANOMALOUS_CONVERSATION",
                                        "PERSONALITY_EXTRAVERSION",
                                        "PERSONALITY_OPEN_TO_EXPERIENCE",
                                        "PERSONALITY_CONSCIENTIOUSNESS",
                                        "PERSONALITY_AGREEABLENESS",
                                        "PERSONALITY_NEUROTICISM",
                                        "PERSONALITY_OTHER",
                                        "DOCUMENT_INSIGHTS",
                                        "CUSTOM"
                                      ]
                                    },
                                    "evaluationCriteria": {
                                      "description": "REQUIRED non-empty instruction the evaluator follows to assess the input. One or two sentences in plain language: what to assess, and (if structuredDataParams is set) how to populate each declared field. Example: \"Decide whether the user is asking about real-estate availability. Set isAvailability to true only when the user is clearly asking whether a property is available; otherwise false.\" Empty strings, null, or omission make the reasoning useless and are forbidden.",
                                      "type": "string"
                                    },
                                    "evaluationSteps": {
                                      "description": "Ordered evaluation steps for the criteria.",
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    },
                                    "evaluationParams": {
                                      "description": "Parameters used during evaluation (e.g., INPUT, CONTEXT).",
                                      "type": "array",
                                      "items": {
                                        "type": "string",
                                        "enum": [
                                          "INPUT",
                                          "ACTUAL_OUTPUT",
                                          "EXPECTED_OUTPUT",
                                          "CONTEXT",
                                          "RETRIEVAL_CONTEXT",
                                          "EXECUTION_CONTEXT"
                                        ]
                                      }
                                    },
                                    "structuredDataParams": {
                                      "description": "Map of field name to a natural-language description of what to extract. The description should encode both the type and the legal values, e.g. \"true if the user is asking about real-estate availability, false otherwise\" (boolean), \"one of: AVAILABILITY, PRICING, CONTACT, OTHER\" (enum), or \"numeric score 1-5 reflecting urgency\" (number). Each declared field becomes a routing key accessible from transition conditions as \"evaluation.structuredData.<field>\" (and is also flattened into top-level vars for action templates). Prefer this for routing on what the user meant or asked; use scores.mean for confidence/quality routing.",
                                      "anyOf": [
                                        {
                                          "type": "object",
                                          "propertyNames": {
                                            "type": "string"
                                          },
                                          "additionalProperties": {}
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    },
                                    "metadata": {
                                      "description": "Additional metadata for the criteria.",
                                      "anyOf": [
                                        {
                                          "type": "object",
                                          "propertyNames": {
                                            "type": "string"
                                          },
                                          "additionalProperties": {}
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    },
                                    "enabled": {
                                      "description": "Whether this criteria is enabled. Defaults to true.",
                                      "type": "boolean"
                                    }
                                  },
                                  "required": [
                                    "name",
                                    "type",
                                    "evaluationCriteria"
                                  ],
                                  "additionalProperties": false
                                }
                              },
                              "workflow": {
                                "description": "The workflow definition including entry points and execution nodes.",
                                "type": "object",
                                "properties": {
                                  "toolName": {
                                    "description": "The tool name used to invoke this agent in the workflow.",
                                    "type": "string"
                                  },
                                  "toolDescription": {
                                    "description": "A description of what this agent does, shown to the LLM router.",
                                    "type": "string"
                                  },
                                  "executionTimeoutSeconds": {
                                    "description": "Wall-clock ceiling for ONE execution of this workflow, in seconds (30-1800). When the deadline passes the run is aborted — in-flight model calls are cancelled, sub-agents included — and the execution finishes with status TIMED_OUT, with the reason recorded on the nodes that were cut. Optional: an agent that declares nothing keeps the platform behavior (no explicit ceiling). Declare it when the agent legitimately runs for minutes (deep research, long tool chains) so a slow run is never mistaken for a hung one, or when it must never occupy a worker past a known bound. The budget is per attempt: a run resumed after a crash starts a fresh timer.",
                                    "type": "integer",
                                    "minimum": 30,
                                    "maximum": 1800
                                  },
                                  "entryPoints": {
                                    "description": "Entry points into the workflow. MUST contain at least one node ID; an empty array makes the workflow non-executable. When you restructure or rename the first node, update this list in the same operation so it points at the new entry node.",
                                    "minItems": 1,
                                    "type": "array",
                                    "items": {
                                      "anyOf": [
                                        {
                                          "description": "Node ID to use as an unconditional entry point.",
                                          "type": "string"
                                        },
                                        {
                                          "type": "object",
                                          "properties": {
                                            "nodeId": {
                                              "description": "The ID of the entry point node.",
                                              "type": "string"
                                            },
                                            "if": {
                                              "description": "Optional condition that must be met for this entry point to activate.",
                                              "$ref": "#/components/schemas/exportAgent_schema0"
                                            }
                                          },
                                          "required": [
                                            "nodeId"
                                          ],
                                          "additionalProperties": false
                                        }
                                      ]
                                    }
                                  },
                                  "nodes": {
                                    "description": "The workflow nodes: decision, action, subAgent, end, state, hub, jump, clearCache, javascript, or forEach.",
                                    "type": "array",
                                    "items": {
                                      "anyOf": [
                                        {
                                          "type": "object",
                                          "properties": {
                                            "id": {
                                              "description": "Unique identifier for this node.",
                                              "type": "string"
                                            },
                                            "type": {
                                              "type": "string",
                                              "const": "decision"
                                            },
                                            "label": {
                                              "description": "Human-readable label for this decision node.",
                                              "type": "string"
                                            },
                                            "evaluationCriteria": {
                                              "description": "Evaluation criteria IDs (string references) or inline criteria objects.",
                                              "type": "array",
                                              "items": {
                                                "anyOf": [
                                                  {
                                                    "type": "string"
                                                  },
                                                  {
                                                    "type": "object",
                                                    "properties": {
                                                      "id": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "description": "Required non-empty short human-readable name for this criterion (e.g. \"Real-Estate Availability Intent\"). Never an empty string.",
                                                        "type": "string"
                                                      },
                                                      "type": {
                                                        "type": "string",
                                                        "enum": [
                                                          "QUALITY_ENGAGINGNESS",
                                                          "QUALITY_COHERENCE",
                                                          "QUALITY_CONSISTENCY",
                                                          "QUALITY_FLUENCY",
                                                          "QUALITY_RELEVANCE",
                                                          "SECURITY_FINANCIAL_DETECTION",
                                                          "SECURITY_PII_DETECTION",
                                                          "SECURITY_ANOMALOUS_CONVERSATION",
                                                          "PERSONALITY_EXTRAVERSION",
                                                          "PERSONALITY_OPEN_TO_EXPERIENCE",
                                                          "PERSONALITY_CONSCIENTIOUSNESS",
                                                          "PERSONALITY_AGREEABLENESS",
                                                          "PERSONALITY_NEUROTICISM",
                                                          "PERSONALITY_OTHER",
                                                          "DOCUMENT_INSIGHTS",
                                                          "CUSTOM"
                                                        ]
                                                      },
                                                      "evaluationCriteria": {
                                                        "description": "REQUIRED non-empty instruction telling the evaluator what to assess. One or two sentences in plain language: what to evaluate, and — when structuredDataParams is set — how to populate each declared field. Empty strings, null, or omission are forbidden; an empty description leaves the reasoning useless. Example: \"Decide whether the user is asking about real-estate availability. Set isAvailability to true only when the user is clearly asking whether a property is available; otherwise false.\"",
                                                        "type": "string"
                                                      },
                                                      "evaluationSteps": {
                                                        "type": "array",
                                                        "items": {
                                                          "type": "string"
                                                        }
                                                      },
                                                      "structuredDataParams": {
                                                        "anyOf": [
                                                          {
                                                            "type": "object",
                                                            "propertyNames": {
                                                              "type": "string"
                                                            },
                                                            "additionalProperties": {}
                                                          },
                                                          {
                                                            "type": "null"
                                                          }
                                                        ]
                                                      },
                                                      "metadata": {
                                                        "anyOf": [
                                                          {
                                                            "type": "object",
                                                            "propertyNames": {
                                                              "type": "string"
                                                            },
                                                            "additionalProperties": {}
                                                          },
                                                          {
                                                            "type": "null"
                                                          }
                                                        ]
                                                      },
                                                      "enabled": {
                                                        "type": "boolean"
                                                      },
                                                      "applicationId": {
                                                        "type": "number"
                                                      },
                                                      "evaluationParams": {
                                                        "type": "array",
                                                        "items": {
                                                          "type": "string",
                                                          "enum": [
                                                            "INPUT",
                                                            "ACTUAL_OUTPUT",
                                                            "EXPECTED_OUTPUT",
                                                            "CONTEXT",
                                                            "RETRIEVAL_CONTEXT",
                                                            "EXECUTION_CONTEXT"
                                                          ]
                                                        }
                                                      }
                                                    },
                                                    "required": [
                                                      "name",
                                                      "type",
                                                      "evaluationCriteria"
                                                    ],
                                                    "additionalProperties": false
                                                  }
                                                ]
                                              }
                                            },
                                            "transition": {
                                              "description": "Transitions to other nodes based on evaluation results.",
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "if": {
                                                    "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                    "$ref": "#/components/schemas/exportAgent_schema0"
                                                  },
                                                  "default": {
                                                    "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                    "type": "boolean"
                                                  },
                                                  "to": {
                                                    "type": "object",
                                                    "properties": {
                                                      "nodeId": {
                                                        "description": "The ID of the target node to transition to.",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "nodeId"
                                                    ],
                                                    "additionalProperties": false
                                                  },
                                                  "stop": {
                                                    "description": "If true, stop execution after this transition.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "to"
                                                ],
                                                "additionalProperties": false
                                              }
                                            },
                                            "cachePolicy": {
                                              "description": "Controls execution caching for this decision node across messages in a conversation. auto (default): cache result and use a lightweight guard evaluation to detect staleness. always: always use cached result until explicitly cleared. never: always re-evaluate all criteria every message (disables caching).",
                                              "type": "string",
                                              "enum": [
                                                "auto",
                                                "always",
                                                "never"
                                              ]
                                            },
                                            "selectionPolicy": {
                                              "description": "Controls which enabled criteria are evaluated each message. all (default): every enabled criterion runs. contextual: a lightweight router selects only the criteria relevant to the current input and conversation state; the rest are skipped. Skipped criteria are not evaluated, so their structuredData fields are absent downstream (route on them with the \"exists\"/\"notExists\" operators) and scores.mean reflects only the criteria that ran.",
                                              "type": "string",
                                              "enum": [
                                                "all",
                                                "contextual"
                                              ]
                                            },
                                            "alwaysRunCriteria": {
                                              "description": "Only used when selectionPolicy is \"contextual\": IDs of evaluation criteria that always run (they bypass the router); every other criterion is AI-selected per message. Use this to pin extractors whose structuredData a downstream node depends on. Ignored when selectionPolicy is \"all\".",
                                              "type": "array",
                                              "items": {
                                                "type": "string"
                                              }
                                            },
                                            "contextualSelectionPrompt": {
                                              "description": "Only used when selectionPolicy is \"contextual\": extra author guidance appended to the built-in router prompt to steer which criteria it picks (e.g. \"prefer running Consultar NFSe whenever the user mentions a nota fiscal, even indirectly\"). It augments the router — it does not replace its output contract or the safe fallback of running everything. Ignored when selectionPolicy is \"all\".",
                                              "type": "string"
                                            },
                                            "routingPolicy": {
                                              "description": "How many REASONINGS (criteria) may win the routing on this node per message. all (default): every matching conditional transition fires in parallel. bestReasoning: only the highest-scoring reasoning wins — ALL matched transitions whose condition is anchored on it fire (they are that reasoning's flow), everything anchored on other reasonings is suppressed. topReasonings: like bestReasoning but the best `maxReasonings` reasonings win. A matched transition is anchored on the highest-scoring criterion its condition references (via \"resultsById.<id>.score\" paths, at any nesting). Score ties between reasonings break by position in this node's evaluationCriteria list (earlier wins) — reorder the list to set priority. Matched transitions that reference NO criterion score (pure structuredData/context/state conditions) are outside the competition and always fire, like \"default\" and unconditional transitions. Criteria evaluation is unaffected — this arbitrates AFTER scoring, so it is the reliable way to get \"only one reasoning wins\" (independent per-criterion evaluations cannot be prompted into exclusivity).",
                                              "type": "string",
                                              "enum": [
                                                "all",
                                                "bestReasoning",
                                                "topReasonings"
                                              ]
                                            },
                                            "maxReasonings": {
                                              "description": "Only used when routingPolicy is \"topReasonings\": how many of the highest-scoring reasonings win the routing. Ignored for other policies (\"bestReasoning\" is exactly maxReasonings = 1).",
                                              "type": "integer",
                                              "minimum": 1,
                                              "maximum": 9007199254740991
                                            }
                                          },
                                          "required": [
                                            "id",
                                            "type",
                                            "evaluationCriteria",
                                            "transition"
                                          ],
                                          "additionalProperties": false
                                        },
                                        {
                                          "oneOf": [
                                            {
                                              "type": "object",
                                              "properties": {
                                                "id": {
                                                  "description": "Unique identifier for this node.",
                                                  "type": "string"
                                                },
                                                "type": {
                                                  "type": "string",
                                                  "const": "action"
                                                },
                                                "label": {
                                                  "description": "Human-readable label for this action node.",
                                                  "type": "string"
                                                },
                                                "mode": {
                                                  "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                  "type": "string",
                                                  "enum": [
                                                    "sync",
                                                    "async"
                                                  ]
                                                },
                                                "outputVar": {
                                                  "description": "Variable name to store the action output for use by downstream nodes.",
                                                  "type": "string"
                                                },
                                                "transition": {
                                                  "description": "Transitions to other nodes after this action completes.",
                                                  "type": "array",
                                                  "items": {
                                                    "type": "object",
                                                    "properties": {
                                                      "if": {
                                                        "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                        "$ref": "#/components/schemas/exportAgent_schema0"
                                                      },
                                                      "default": {
                                                        "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                        "type": "boolean"
                                                      },
                                                      "to": {
                                                        "type": "object",
                                                        "properties": {
                                                          "nodeId": {
                                                            "description": "The ID of the target node to transition to.",
                                                            "type": "string"
                                                          }
                                                        },
                                                        "required": [
                                                          "nodeId"
                                                        ],
                                                        "additionalProperties": false
                                                      },
                                                      "stop": {
                                                        "description": "If true, stop execution after this transition.",
                                                        "type": "boolean"
                                                      }
                                                    },
                                                    "required": [
                                                      "to"
                                                    ],
                                                    "additionalProperties": false
                                                  }
                                                },
                                                "actionType": {
                                                  "type": "string",
                                                  "const": "INSTRUCTIONS"
                                                },
                                                "config": {
                                                  "type": "object",
                                                  "properties": {
                                                    "instructions": {
                                                      "description": "The instructions for the LLM to execute.",
                                                      "type": "string"
                                                    },
                                                    "modelTier": {
                                                      "description": "The model tier to use for this instruction. Defaults to regular.",
                                                      "type": "string",
                                                      "enum": [
                                                        "lite",
                                                        "regular",
                                                        "pro"
                                                      ]
                                                    },
                                                    "thinkingEffortPct": {
                                                      "description": "Thinking effort percentage (0-100) controlling how much reasoning the model applies.",
                                                      "type": "number",
                                                      "minimum": 0,
                                                      "maximum": 100
                                                    },
                                                    "maxOutputTokens": {
                                                      "description": "Maximum tokens the model may generate for this node. On thinking models the budget is SHARED between reasoning and output — reasoning routinely consumes most of it — so a node whose structured output is truncated is usually better served by lowering thinkingEffortPct than by raising this. Defaults to the model maximum when omitted.",
                                                      "type": "integer",
                                                      "minimum": 1,
                                                      "maximum": 9007199254740991
                                                    },
                                                    "maxRetries": {
                                                      "description": "How many times this node retries a failed model call. Defaults to 2 when the node has an outputSchema and 5 otherwise. Raise it for nodes whose long outputs are exposed to dropped provider streams; it does not help failures the model reproduces deterministically.",
                                                      "type": "integer",
                                                      "minimum": 1,
                                                      "maximum": 10
                                                    },
                                                    "toolChoiceMode": {
                                                      "description": "Tool selection mode for this instruction. Defaults to auto when omitted.",
                                                      "type": "string",
                                                      "enum": [
                                                        "auto",
                                                        "none",
                                                        "tool",
                                                        "tools"
                                                      ]
                                                    },
                                                    "toolChoiceToolName": {
                                                      "description": "When toolChoiceMode is \"tool\", the specific tool name to force.",
                                                      "type": "string"
                                                    },
                                                    "toolChoiceToolNames": {
                                                      "description": "When toolChoiceMode is \"tools\", the list of allowed tool names.",
                                                      "type": "array",
                                                      "items": {
                                                        "type": "string"
                                                      }
                                                    },
                                                    "suppressTextResponse": {
                                                      "description": "When true, text output from the LLM is suppressed and only tool-call results are emitted. Useful when the instruction should only invoke tools (e.g., displayMedia) without generating follow-up text.",
                                                      "type": "boolean"
                                                    },
                                                    "stopAfterFirstToolCall": {
                                                      "description": "When true and a single tool is forced with text suppressed, the instruction stops after the first successful tool call. Defaults to false, which allows the tool to be called across multiple steps.",
                                                      "type": "boolean"
                                                    },
                                                    "internal": {
                                                      "description": "When true, this node is an intermediate step: its text/structured output is NOT shown to the user (not streamed, not persisted as a visible message part) and is only captured into the node's outputVar for downstream nodes. Reasoning and tool-call activity chips remain visible. Use for internal hand-offs (e.g. tool-driven data synthesis a later node consumes); the user-facing reply should come from a later, non-internal node.",
                                                      "type": "boolean"
                                                    },
                                                    "outputSchema": {
                                                      "description": "JSON Schema for structured output. When provided, the LLM will output valid JSON matching this schema instead of free-form text.",
                                                      "type": "object",
                                                      "properties": {
                                                        "type": {
                                                          "description": "JSON Schema type, must be \"object\" for structured output.",
                                                          "type": "string",
                                                          "const": "object"
                                                        },
                                                        "properties": {
                                                          "description": "Schema properties defining the expected output structure.",
                                                          "type": "object",
                                                          "propertyNames": {
                                                            "type": "string"
                                                          },
                                                          "additionalProperties": {}
                                                        },
                                                        "required": {
                                                          "description": "Array of required property names.",
                                                          "type": "array",
                                                          "items": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "additionalProperties": {
                                                          "description": "Whether to allow additional properties not defined in the schema.",
                                                          "type": "boolean"
                                                        },
                                                        "description": {
                                                          "description": "Description of the expected output to guide the LLM.",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "required": [
                                                        "type",
                                                        "properties"
                                                      ],
                                                      "additionalProperties": false
                                                    },
                                                    "grounding": {
                                                      "description": "Model-side grounding for this node. Only Google Search is available today.",
                                                      "type": "object",
                                                      "properties": {
                                                        "googleSearch": {
                                                          "description": "Enable Google Search grounding: the model searches the public web (via Gemini's built-in google_search tool) while executing this instruction and answers from what it finds. Set `{}` to enable with defaults. The node result then carries `grounding` — the queries Google ran and the sources it cited, each with the resolved article URL, its domain and the passages of the reply it supports — readable downstream as `nodes.<nodeId>.grounding` in javascript nodes and templates; the text/JSON reply itself still flows through outputVar as usual. With an outputSchema the search runs first and the JSON is synthesized afterwards with the numbered source list, so declare a `sourceIds` or `url` field if you want citations inside the structured output. Incompatible with toolChoiceMode \"tool\" and with suppressTextResponse (a forced tool call and Google Search in one request returns an empty reply); with toolChoiceMode \"none\" the node still searches but calls no other tool. Each prompt costs Google one search query per query the model decides to run (usually 4–10), billed per query beyond the project's free tier.",
                                                          "type": "object",
                                                          "properties": {
                                                            "excludeDomains": {
                                                              "description": "Domains Google Search must not ground on, e.g. [\"youtube.com\", \"reddit.com\"]. A domain excludes its subdomains too.",
                                                              "type": "array",
                                                              "items": {
                                                                "type": "string"
                                                              }
                                                            }
                                                          },
                                                          "additionalProperties": false
                                                        }
                                                      },
                                                      "additionalProperties": false
                                                    },
                                                    "urlContext": {
                                                      "description": "Gemini URL context: hand the model a list of URLs to READ IN FULL server-side instead of fetching their text into a variable first. The URLs come from the fixed \"urls\" list, from the \"from\" value path, or from both (fixed first). They are appended to the end of the instruction and the provider fetches and reads the pages inside the same call. With an outputSchema the node runs as a SINGLE call (reading and synthesis must share it), so pair it with toolChoiceMode \"none\" unless the node truly needs function tools. Limits: 20 URLs per call (extra ones are dropped and reported as `truncated`), public pages only — paywalls, Google News redirect links and private hosts fail. The model may skip fetching when the URLs sit inside a very long prompt, so prefer a dedicated short reading node over bolting URLs onto a large synthesis prompt. The node output carries `urlContext.{requested,retrieved,unread,truncated,invalid,unresolved,supported,tokens}`. `unread` is the integrity signal — it lists every URL the model did not read, including the ones dropped by the 20-URL cap — so branch on `nodes.<id>.urlContext.unread` for a fallback reader (inside a forEach body it holds only the last item). `unresolved` says the \"from\" path resolved to nothing, `invalid` lists entries that were not http(s) URLs, and `supported` is false when the model could not carry the tool: in those cases nothing was read at all. Retrieved page content is billed as input tokens and added to the node usage as `urlContextTokens`. Gemini 3+ models only.",
                                                      "type": "object",
                                                      "properties": {
                                                        "urls": {
                                                          "description": "Fixed http(s) URLs to read on every run, written out here — for pages that do not change per execution (a status page, a policy, a price list). Combine with \"from\" to read a fixed set plus whatever the run produced; the two lists concatenate, fixed URLs first.",
                                                          "type": "array",
                                                          "items": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "from": {
                                                          "description": "Dotted VALUE PATH (same resolution as forEach \"over\": workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — e.g. \"paraLer.soUrls\" or \"nodes.pick.result.urls\") to a URL list the run produced: an array of http(s) URL strings, a single URL string, or a JSON-encoded array string. Not a Handlebars template; a path wrapped in {{ }} is accepted and unwrapped.",
                                                          "type": "string",
                                                          "minLength": 1
                                                        }
                                                      },
                                                      "additionalProperties": false
                                                    }
                                                  },
                                                  "required": [
                                                    "instructions"
                                                  ],
                                                  "additionalProperties": false
                                                }
                                              },
                                              "required": [
                                                "id",
                                                "type",
                                                "mode",
                                                "transition",
                                                "actionType",
                                                "config"
                                              ],
                                              "additionalProperties": false
                                            },
                                            {
                                              "type": "object",
                                              "properties": {
                                                "id": {
                                                  "description": "Unique identifier for this node.",
                                                  "type": "string"
                                                },
                                                "type": {
                                                  "type": "string",
                                                  "const": "action"
                                                },
                                                "label": {
                                                  "description": "Human-readable label for this action node.",
                                                  "type": "string"
                                                },
                                                "mode": {
                                                  "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                  "type": "string",
                                                  "enum": [
                                                    "sync",
                                                    "async"
                                                  ]
                                                },
                                                "outputVar": {
                                                  "description": "Variable name to store the action output for use by downstream nodes.",
                                                  "type": "string"
                                                },
                                                "transition": {
                                                  "description": "Transitions to other nodes after this action completes.",
                                                  "type": "array",
                                                  "items": {
                                                    "type": "object",
                                                    "properties": {
                                                      "if": {
                                                        "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                        "$ref": "#/components/schemas/exportAgent_schema0"
                                                      },
                                                      "default": {
                                                        "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                        "type": "boolean"
                                                      },
                                                      "to": {
                                                        "type": "object",
                                                        "properties": {
                                                          "nodeId": {
                                                            "description": "The ID of the target node to transition to.",
                                                            "type": "string"
                                                          }
                                                        },
                                                        "required": [
                                                          "nodeId"
                                                        ],
                                                        "additionalProperties": false
                                                      },
                                                      "stop": {
                                                        "description": "If true, stop execution after this transition.",
                                                        "type": "boolean"
                                                      }
                                                    },
                                                    "required": [
                                                      "to"
                                                    ],
                                                    "additionalProperties": false
                                                  }
                                                },
                                                "actionType": {
                                                  "type": "string",
                                                  "const": "EMAIL"
                                                },
                                                "config": {
                                                  "type": "object",
                                                  "properties": {
                                                    "to": {
                                                      "type": "string"
                                                    },
                                                    "senderType": {
                                                      "type": "string",
                                                      "enum": [
                                                        "default",
                                                        "gmail"
                                                      ]
                                                    },
                                                    "gmailIntegrationId": {
                                                      "type": "string"
                                                    },
                                                    "subject": {
                                                      "type": "string"
                                                    },
                                                    "body": {
                                                      "type": "string"
                                                    },
                                                    "cc": {
                                                      "type": "string"
                                                    },
                                                    "bcc": {
                                                      "type": "string"
                                                    },
                                                    "attachments": {
                                                      "type": "array",
                                                      "items": {
                                                        "type": "object",
                                                        "properties": {
                                                          "documentId": {
                                                            "type": "number"
                                                          },
                                                          "url": {
                                                            "type": "string"
                                                          },
                                                          "filename": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "additionalProperties": false
                                                      }
                                                    },
                                                    "templateId": {
                                                      "type": "string"
                                                    },
                                                    "templateName": {
                                                      "type": "string"
                                                    },
                                                    "applicationId": {
                                                      "type": "number"
                                                    }
                                                  },
                                                  "required": [
                                                    "to",
                                                    "subject",
                                                    "body"
                                                  ],
                                                  "additionalProperties": false
                                                }
                                              },
                                              "required": [
                                                "id",
                                                "type",
                                                "mode",
                                                "transition",
                                                "actionType",
                                                "config"
                                              ],
                                              "additionalProperties": false
                                            },
                                            {
                                              "type": "object",
                                              "properties": {
                                                "id": {
                                                  "description": "Unique identifier for this node.",
                                                  "type": "string"
                                                },
                                                "type": {
                                                  "type": "string",
                                                  "const": "action"
                                                },
                                                "label": {
                                                  "description": "Human-readable label for this action node.",
                                                  "type": "string"
                                                },
                                                "mode": {
                                                  "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                  "type": "string",
                                                  "enum": [
                                                    "sync",
                                                    "async"
                                                  ]
                                                },
                                                "outputVar": {
                                                  "description": "Variable name to store the action output for use by downstream nodes.",
                                                  "type": "string"
                                                },
                                                "transition": {
                                                  "description": "Transitions to other nodes after this action completes.",
                                                  "type": "array",
                                                  "items": {
                                                    "type": "object",
                                                    "properties": {
                                                      "if": {
                                                        "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                        "$ref": "#/components/schemas/exportAgent_schema0"
                                                      },
                                                      "default": {
                                                        "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                        "type": "boolean"
                                                      },
                                                      "to": {
                                                        "type": "object",
                                                        "properties": {
                                                          "nodeId": {
                                                            "description": "The ID of the target node to transition to.",
                                                            "type": "string"
                                                          }
                                                        },
                                                        "required": [
                                                          "nodeId"
                                                        ],
                                                        "additionalProperties": false
                                                      },
                                                      "stop": {
                                                        "description": "If true, stop execution after this transition.",
                                                        "type": "boolean"
                                                      }
                                                    },
                                                    "required": [
                                                      "to"
                                                    ],
                                                    "additionalProperties": false
                                                  }
                                                },
                                                "actionType": {
                                                  "type": "string",
                                                  "const": "WEBHOOK"
                                                },
                                                "config": {
                                                  "type": "object",
                                                  "properties": {
                                                    "url": {
                                                      "type": "string"
                                                    },
                                                    "method": {
                                                      "type": "string",
                                                      "enum": [
                                                        "GET",
                                                        "POST",
                                                        "PUT",
                                                        "PATCH",
                                                        "DELETE"
                                                      ]
                                                    },
                                                    "headers": {
                                                      "type": "object",
                                                      "propertyNames": {
                                                        "type": "string"
                                                      },
                                                      "additionalProperties": {
                                                        "type": "string"
                                                      }
                                                    },
                                                    "queryParams": {
                                                      "type": "object",
                                                      "propertyNames": {
                                                        "type": "string"
                                                      },
                                                      "additionalProperties": {
                                                        "type": "string"
                                                      }
                                                    },
                                                    "body": {
                                                      "type": "string"
                                                    },
                                                    "timeout": {
                                                      "type": "number"
                                                    },
                                                    "responseMode": {
                                                      "description": "How to decode the response body. \"json\" (default): parse as JSON/text and expose via varsDelta. \"attachment\": read as binary bytes for multimodal input (e.g. PDFs, images).",
                                                      "type": "string",
                                                      "enum": [
                                                        "json",
                                                        "attachment"
                                                      ]
                                                    },
                                                    "asMessage": {
                                                      "description": "When true, append the response to the conversation as a new user message so downstream LLM nodes see it. In \"attachment\" mode the message carries a file content part; in \"json\" mode it carries the stringified body as text. Defaults to false — preserving the historical behavior where webhook responses only flow through varsDelta.",
                                                      "type": "boolean"
                                                    },
                                                    "suppressNoResponseFallback": {
                                                      "description": "Marks the webhook as a fire-and-forget trigger: the conversation is meant to end here, with the rest happening on the receiving system. When the call succeeds and the turn finishes without sending anything to the user, the channel skips its automatic \"sorry, something went wrong\" fallback message. A failed call (HTTP >= 400) still gets the fallback, since the user is then left waiting for nothing.",
                                                      "type": "boolean"
                                                    }
                                                  },
                                                  "required": [
                                                    "url",
                                                    "method"
                                                  ],
                                                  "additionalProperties": false
                                                }
                                              },
                                              "required": [
                                                "id",
                                                "type",
                                                "mode",
                                                "transition",
                                                "actionType",
                                                "config"
                                              ],
                                              "additionalProperties": false
                                            },
                                            {
                                              "type": "object",
                                              "properties": {
                                                "id": {
                                                  "description": "Unique identifier for this node.",
                                                  "type": "string"
                                                },
                                                "type": {
                                                  "type": "string",
                                                  "const": "action"
                                                },
                                                "label": {
                                                  "description": "Human-readable label for this action node.",
                                                  "type": "string"
                                                },
                                                "mode": {
                                                  "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                  "type": "string",
                                                  "enum": [
                                                    "sync",
                                                    "async"
                                                  ]
                                                },
                                                "outputVar": {
                                                  "description": "Variable name to store the action output for use by downstream nodes.",
                                                  "type": "string"
                                                },
                                                "transition": {
                                                  "description": "Transitions to other nodes after this action completes.",
                                                  "type": "array",
                                                  "items": {
                                                    "type": "object",
                                                    "properties": {
                                                      "if": {
                                                        "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                        "$ref": "#/components/schemas/exportAgent_schema0"
                                                      },
                                                      "default": {
                                                        "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                        "type": "boolean"
                                                      },
                                                      "to": {
                                                        "type": "object",
                                                        "properties": {
                                                          "nodeId": {
                                                            "description": "The ID of the target node to transition to.",
                                                            "type": "string"
                                                          }
                                                        },
                                                        "required": [
                                                          "nodeId"
                                                        ],
                                                        "additionalProperties": false
                                                      },
                                                      "stop": {
                                                        "description": "If true, stop execution after this transition.",
                                                        "type": "boolean"
                                                      }
                                                    },
                                                    "required": [
                                                      "to"
                                                    ],
                                                    "additionalProperties": false
                                                  }
                                                },
                                                "actionType": {
                                                  "type": "string",
                                                  "const": "DOCUMENT_TEMPLATE"
                                                },
                                                "config": {
                                                  "type": "object",
                                                  "properties": {
                                                    "templateId": {
                                                      "type": "string"
                                                    },
                                                    "templateName": {
                                                      "type": "string"
                                                    },
                                                    "sendEmail": {
                                                      "type": "boolean"
                                                    },
                                                    "sendWhatsApp": {
                                                      "type": "boolean"
                                                    },
                                                    "recipientEmail": {
                                                      "type": "string"
                                                    }
                                                  },
                                                  "required": [
                                                    "templateId"
                                                  ],
                                                  "additionalProperties": false
                                                }
                                              },
                                              "required": [
                                                "id",
                                                "type",
                                                "mode",
                                                "transition",
                                                "actionType",
                                                "config"
                                              ],
                                              "additionalProperties": false
                                            },
                                            {
                                              "type": "object",
                                              "properties": {
                                                "id": {
                                                  "description": "Unique identifier for this node.",
                                                  "type": "string"
                                                },
                                                "type": {
                                                  "type": "string",
                                                  "const": "action"
                                                },
                                                "label": {
                                                  "description": "Human-readable label for this action node.",
                                                  "type": "string"
                                                },
                                                "mode": {
                                                  "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                  "type": "string",
                                                  "enum": [
                                                    "sync",
                                                    "async"
                                                  ]
                                                },
                                                "outputVar": {
                                                  "description": "Variable name to store the action output for use by downstream nodes.",
                                                  "type": "string"
                                                },
                                                "transition": {
                                                  "description": "Transitions to other nodes after this action completes.",
                                                  "type": "array",
                                                  "items": {
                                                    "type": "object",
                                                    "properties": {
                                                      "if": {
                                                        "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                        "$ref": "#/components/schemas/exportAgent_schema0"
                                                      },
                                                      "default": {
                                                        "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                        "type": "boolean"
                                                      },
                                                      "to": {
                                                        "type": "object",
                                                        "properties": {
                                                          "nodeId": {
                                                            "description": "The ID of the target node to transition to.",
                                                            "type": "string"
                                                          }
                                                        },
                                                        "required": [
                                                          "nodeId"
                                                        ],
                                                        "additionalProperties": false
                                                      },
                                                      "stop": {
                                                        "description": "If true, stop execution after this transition.",
                                                        "type": "boolean"
                                                      }
                                                    },
                                                    "required": [
                                                      "to"
                                                    ],
                                                    "additionalProperties": false
                                                  }
                                                },
                                                "actionType": {
                                                  "type": "string",
                                                  "const": "TOOL_CALL"
                                                },
                                                "config": {
                                                  "type": "object",
                                                  "properties": {
                                                    "toolName": {
                                                      "description": "The name of the common tool to invoke.",
                                                      "type": "string"
                                                    },
                                                    "parameters": {
                                                      "description": "Per-parameter configuration. Keys are parameter names from the tool schema.",
                                                      "type": "object",
                                                      "propertyNames": {
                                                        "type": "string"
                                                      },
                                                      "additionalProperties": {
                                                        "type": "object",
                                                        "properties": {
                                                          "mode": {
                                                            "description": "Whether this parameter is hardcoded (static) or filled by the LLM at runtime (dynamic).",
                                                            "type": "string",
                                                            "enum": [
                                                              "static",
                                                              "dynamic"
                                                            ]
                                                          },
                                                          "staticValue": {
                                                            "description": "The fixed value for this parameter. Required when mode is \"static\"."
                                                          },
                                                          "instructions": {
                                                            "description": "Optional guidance for the LLM when filling this parameter (only used when mode is \"dynamic\").",
                                                            "type": "string"
                                                          }
                                                        },
                                                        "required": [
                                                          "mode"
                                                        ],
                                                        "additionalProperties": false
                                                      }
                                                    },
                                                    "instructions": {
                                                      "description": "General instructions for the LLM when resolving dynamic parameters.",
                                                      "type": "string"
                                                    },
                                                    "skipKnowledgeSearch": {
                                                      "description": "When a node has dynamic parameters, the model is normally forced to call similaritySearch first so parameter values are grounded in the knowledge base, costing one extra model round. Set true for tools that need no knowledge context (for example code execution) to call the configured tool directly. Ignored when every parameter is static, since no model runs at all.",
                                                      "type": "boolean"
                                                    }
                                                  },
                                                  "required": [
                                                    "toolName"
                                                  ],
                                                  "additionalProperties": false
                                                }
                                              },
                                              "required": [
                                                "id",
                                                "type",
                                                "mode",
                                                "transition",
                                                "actionType",
                                                "config"
                                              ],
                                              "additionalProperties": false
                                            },
                                            {
                                              "type": "object",
                                              "properties": {
                                                "id": {
                                                  "description": "Unique identifier for this node.",
                                                  "type": "string"
                                                },
                                                "type": {
                                                  "type": "string",
                                                  "const": "action"
                                                },
                                                "label": {
                                                  "description": "Human-readable label for this action node.",
                                                  "type": "string"
                                                },
                                                "mode": {
                                                  "description": "Execution mode: sync blocks until complete, async runs in parallel.",
                                                  "type": "string",
                                                  "enum": [
                                                    "sync",
                                                    "async"
                                                  ]
                                                },
                                                "outputVar": {
                                                  "description": "Variable name to store the action output for use by downstream nodes.",
                                                  "type": "string"
                                                },
                                                "transition": {
                                                  "description": "Transitions to other nodes after this action completes.",
                                                  "type": "array",
                                                  "items": {
                                                    "type": "object",
                                                    "properties": {
                                                      "if": {
                                                        "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                        "$ref": "#/components/schemas/exportAgent_schema0"
                                                      },
                                                      "default": {
                                                        "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                        "type": "boolean"
                                                      },
                                                      "to": {
                                                        "type": "object",
                                                        "properties": {
                                                          "nodeId": {
                                                            "description": "The ID of the target node to transition to.",
                                                            "type": "string"
                                                          }
                                                        },
                                                        "required": [
                                                          "nodeId"
                                                        ],
                                                        "additionalProperties": false
                                                      },
                                                      "stop": {
                                                        "description": "If true, stop execution after this transition.",
                                                        "type": "boolean"
                                                      }
                                                    },
                                                    "required": [
                                                      "to"
                                                    ],
                                                    "additionalProperties": false
                                                  }
                                                },
                                                "actionType": {
                                                  "type": "string",
                                                  "const": "FOLLOW_UP"
                                                },
                                                "config": {
                                                  "type": "object",
                                                  "properties": {
                                                    "delayMinutes": {
                                                      "description": "Minutes to wait before checking whether to run the inner action. Common presets: 5, 10, 15. Maximum 1440 (24h). Cloud Scheduler is cron-based so the actual fire time is rounded to the next minute boundary.",
                                                      "type": "integer",
                                                      "minimum": 1,
                                                      "maximum": 1440
                                                    },
                                                    "cancelOnUserMessage": {
                                                      "description": "When true (default), skip the inner action if any USER message arrived after the node was reached. Set to false only if the follow-up should fire even after the user has replied.",
                                                      "type": "boolean"
                                                    },
                                                    "cancelOnAssistantMessage": {
                                                      "description": "When true (default), skip the inner action if any ASSISTANT text message was sent after the node was reached. Tool-only assistant messages (no text content) do NOT count. Prevents double-pinging when another node already produced a response.",
                                                      "type": "boolean"
                                                    },
                                                    "cancelOnArchive": {
                                                      "description": "When true (default), skip the inner action if the thread was archived between scheduling and firing.",
                                                      "type": "boolean"
                                                    },
                                                    "action": {
                                                      "description": "The inner action to run when the delay elapses and cancel rules pass. INSTRUCTIONS produces an LLM-generated text message (good for \"Are you still there?\"-style nudges). TOOL_CALL fires a display tool (good for offering options or showing media).",
                                                      "oneOf": [
                                                        {
                                                          "type": "object",
                                                          "properties": {
                                                            "actionType": {
                                                              "type": "string",
                                                              "const": "INSTRUCTIONS"
                                                            },
                                                            "config": {
                                                              "type": "object",
                                                              "properties": {
                                                                "instructions": {
                                                                  "description": "The instructions for the LLM to execute.",
                                                                  "type": "string"
                                                                },
                                                                "modelTier": {
                                                                  "description": "The model tier to use for this instruction. Defaults to regular.",
                                                                  "type": "string",
                                                                  "enum": [
                                                                    "lite",
                                                                    "regular",
                                                                    "pro"
                                                                  ]
                                                                },
                                                                "thinkingEffortPct": {
                                                                  "description": "Thinking effort percentage (0-100) controlling how much reasoning the model applies.",
                                                                  "type": "number",
                                                                  "minimum": 0,
                                                                  "maximum": 100
                                                                },
                                                                "maxOutputTokens": {
                                                                  "description": "Maximum tokens the model may generate for this node. On thinking models the budget is SHARED between reasoning and output — reasoning routinely consumes most of it — so a node whose structured output is truncated is usually better served by lowering thinkingEffortPct than by raising this. Defaults to the model maximum when omitted.",
                                                                  "type": "integer",
                                                                  "minimum": 1,
                                                                  "maximum": 9007199254740991
                                                                },
                                                                "maxRetries": {
                                                                  "description": "How many times this node retries a failed model call. Defaults to 2 when the node has an outputSchema and 5 otherwise. Raise it for nodes whose long outputs are exposed to dropped provider streams; it does not help failures the model reproduces deterministically.",
                                                                  "type": "integer",
                                                                  "minimum": 1,
                                                                  "maximum": 10
                                                                },
                                                                "toolChoiceMode": {
                                                                  "description": "Tool selection mode for this instruction. Defaults to auto when omitted.",
                                                                  "type": "string",
                                                                  "enum": [
                                                                    "auto",
                                                                    "none",
                                                                    "tool",
                                                                    "tools"
                                                                  ]
                                                                },
                                                                "toolChoiceToolName": {
                                                                  "description": "When toolChoiceMode is \"tool\", the specific tool name to force.",
                                                                  "type": "string"
                                                                },
                                                                "toolChoiceToolNames": {
                                                                  "description": "When toolChoiceMode is \"tools\", the list of allowed tool names.",
                                                                  "type": "array",
                                                                  "items": {
                                                                    "type": "string"
                                                                  }
                                                                },
                                                                "suppressTextResponse": {
                                                                  "description": "When true, text output from the LLM is suppressed and only tool-call results are emitted. Useful when the instruction should only invoke tools (e.g., displayMedia) without generating follow-up text.",
                                                                  "type": "boolean"
                                                                },
                                                                "stopAfterFirstToolCall": {
                                                                  "description": "When true and a single tool is forced with text suppressed, the instruction stops after the first successful tool call. Defaults to false, which allows the tool to be called across multiple steps.",
                                                                  "type": "boolean"
                                                                },
                                                                "internal": {
                                                                  "description": "When true, this node is an intermediate step: its text/structured output is NOT shown to the user (not streamed, not persisted as a visible message part) and is only captured into the node's outputVar for downstream nodes. Reasoning and tool-call activity chips remain visible. Use for internal hand-offs (e.g. tool-driven data synthesis a later node consumes); the user-facing reply should come from a later, non-internal node.",
                                                                  "type": "boolean"
                                                                },
                                                                "outputSchema": {
                                                                  "description": "JSON Schema for structured output. When provided, the LLM will output valid JSON matching this schema instead of free-form text.",
                                                                  "type": "object",
                                                                  "properties": {
                                                                    "type": {
                                                                      "description": "JSON Schema type, must be \"object\" for structured output.",
                                                                      "type": "string",
                                                                      "const": "object"
                                                                    },
                                                                    "properties": {
                                                                      "description": "Schema properties defining the expected output structure.",
                                                                      "type": "object",
                                                                      "propertyNames": {
                                                                        "type": "string"
                                                                      },
                                                                      "additionalProperties": {}
                                                                    },
                                                                    "required": {
                                                                      "description": "Array of required property names.",
                                                                      "type": "array",
                                                                      "items": {
                                                                        "type": "string"
                                                                      }
                                                                    },
                                                                    "additionalProperties": {
                                                                      "description": "Whether to allow additional properties not defined in the schema.",
                                                                      "type": "boolean"
                                                                    },
                                                                    "description": {
                                                                      "description": "Description of the expected output to guide the LLM.",
                                                                      "type": "string"
                                                                    }
                                                                  },
                                                                  "required": [
                                                                    "type",
                                                                    "properties"
                                                                  ],
                                                                  "additionalProperties": false
                                                                },
                                                                "grounding": {
                                                                  "description": "Model-side grounding for this node. Only Google Search is available today.",
                                                                  "type": "object",
                                                                  "properties": {
                                                                    "googleSearch": {
                                                                      "description": "Enable Google Search grounding: the model searches the public web (via Gemini's built-in google_search tool) while executing this instruction and answers from what it finds. Set `{}` to enable with defaults. The node result then carries `grounding` — the queries Google ran and the sources it cited, each with the resolved article URL, its domain and the passages of the reply it supports — readable downstream as `nodes.<nodeId>.grounding` in javascript nodes and templates; the text/JSON reply itself still flows through outputVar as usual. With an outputSchema the search runs first and the JSON is synthesized afterwards with the numbered source list, so declare a `sourceIds` or `url` field if you want citations inside the structured output. Incompatible with toolChoiceMode \"tool\" and with suppressTextResponse (a forced tool call and Google Search in one request returns an empty reply); with toolChoiceMode \"none\" the node still searches but calls no other tool. Each prompt costs Google one search query per query the model decides to run (usually 4–10), billed per query beyond the project's free tier.",
                                                                      "type": "object",
                                                                      "properties": {
                                                                        "excludeDomains": {
                                                                          "description": "Domains Google Search must not ground on, e.g. [\"youtube.com\", \"reddit.com\"]. A domain excludes its subdomains too.",
                                                                          "type": "array",
                                                                          "items": {
                                                                            "type": "string"
                                                                          }
                                                                        }
                                                                      },
                                                                      "additionalProperties": false
                                                                    }
                                                                  },
                                                                  "additionalProperties": false
                                                                },
                                                                "urlContext": {
                                                                  "description": "Gemini URL context: hand the model a list of URLs to READ IN FULL server-side instead of fetching their text into a variable first. The URLs come from the fixed \"urls\" list, from the \"from\" value path, or from both (fixed first). They are appended to the end of the instruction and the provider fetches and reads the pages inside the same call. With an outputSchema the node runs as a SINGLE call (reading and synthesis must share it), so pair it with toolChoiceMode \"none\" unless the node truly needs function tools. Limits: 20 URLs per call (extra ones are dropped and reported as `truncated`), public pages only — paywalls, Google News redirect links and private hosts fail. The model may skip fetching when the URLs sit inside a very long prompt, so prefer a dedicated short reading node over bolting URLs onto a large synthesis prompt. The node output carries `urlContext.{requested,retrieved,unread,truncated,invalid,unresolved,supported,tokens}`. `unread` is the integrity signal — it lists every URL the model did not read, including the ones dropped by the 20-URL cap — so branch on `nodes.<id>.urlContext.unread` for a fallback reader (inside a forEach body it holds only the last item). `unresolved` says the \"from\" path resolved to nothing, `invalid` lists entries that were not http(s) URLs, and `supported` is false when the model could not carry the tool: in those cases nothing was read at all. Retrieved page content is billed as input tokens and added to the node usage as `urlContextTokens`. Gemini 3+ models only.",
                                                                  "type": "object",
                                                                  "properties": {
                                                                    "urls": {
                                                                      "description": "Fixed http(s) URLs to read on every run, written out here — for pages that do not change per execution (a status page, a policy, a price list). Combine with \"from\" to read a fixed set plus whatever the run produced; the two lists concatenate, fixed URLs first.",
                                                                      "type": "array",
                                                                      "items": {
                                                                        "type": "string"
                                                                      }
                                                                    },
                                                                    "from": {
                                                                      "description": "Dotted VALUE PATH (same resolution as forEach \"over\": workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — e.g. \"paraLer.soUrls\" or \"nodes.pick.result.urls\") to a URL list the run produced: an array of http(s) URL strings, a single URL string, or a JSON-encoded array string. Not a Handlebars template; a path wrapped in {{ }} is accepted and unwrapped.",
                                                                      "type": "string",
                                                                      "minLength": 1
                                                                    }
                                                                  },
                                                                  "additionalProperties": false
                                                                }
                                                              },
                                                              "required": [
                                                                "instructions"
                                                              ],
                                                              "additionalProperties": false
                                                            }
                                                          },
                                                          "required": [
                                                            "actionType",
                                                            "config"
                                                          ],
                                                          "additionalProperties": false
                                                        },
                                                        {
                                                          "type": "object",
                                                          "properties": {
                                                            "actionType": {
                                                              "type": "string",
                                                              "const": "TOOL_CALL"
                                                            },
                                                            "config": {
                                                              "type": "object",
                                                              "properties": {
                                                                "toolName": {
                                                                  "description": "The name of the common tool to invoke.",
                                                                  "type": "string"
                                                                },
                                                                "parameters": {
                                                                  "description": "Per-parameter configuration. Keys are parameter names from the tool schema.",
                                                                  "type": "object",
                                                                  "propertyNames": {
                                                                    "type": "string"
                                                                  },
                                                                  "additionalProperties": {
                                                                    "type": "object",
                                                                    "properties": {
                                                                      "mode": {
                                                                        "description": "Whether this parameter is hardcoded (static) or filled by the LLM at runtime (dynamic).",
                                                                        "type": "string",
                                                                        "enum": [
                                                                          "static",
                                                                          "dynamic"
                                                                        ]
                                                                      },
                                                                      "staticValue": {
                                                                        "description": "The fixed value for this parameter. Required when mode is \"static\"."
                                                                      },
                                                                      "instructions": {
                                                                        "description": "Optional guidance for the LLM when filling this parameter (only used when mode is \"dynamic\").",
                                                                        "type": "string"
                                                                      }
                                                                    },
                                                                    "required": [
                                                                      "mode"
                                                                    ],
                                                                    "additionalProperties": false
                                                                  }
                                                                },
                                                                "instructions": {
                                                                  "description": "General instructions for the LLM when resolving dynamic parameters.",
                                                                  "type": "string"
                                                                },
                                                                "skipKnowledgeSearch": {
                                                                  "description": "When a node has dynamic parameters, the model is normally forced to call similaritySearch first so parameter values are grounded in the knowledge base, costing one extra model round. Set true for tools that need no knowledge context (for example code execution) to call the configured tool directly. Ignored when every parameter is static, since no model runs at all.",
                                                                  "type": "boolean"
                                                                }
                                                              },
                                                              "required": [
                                                                "toolName"
                                                              ],
                                                              "additionalProperties": false
                                                            }
                                                          },
                                                          "required": [
                                                            "actionType",
                                                            "config"
                                                          ],
                                                          "additionalProperties": false
                                                        }
                                                      ]
                                                    }
                                                  },
                                                  "required": [
                                                    "delayMinutes",
                                                    "action"
                                                  ],
                                                  "additionalProperties": false
                                                }
                                              },
                                              "required": [
                                                "id",
                                                "type",
                                                "mode",
                                                "transition",
                                                "actionType",
                                                "config"
                                              ],
                                              "additionalProperties": false
                                            }
                                          ]
                                        },
                                        {
                                          "type": "object",
                                          "properties": {
                                            "id": {
                                              "description": "Unique identifier for this node.",
                                              "type": "string"
                                            },
                                            "type": {
                                              "type": "string",
                                              "const": "subAgent"
                                            },
                                            "label": {
                                              "description": "Human-readable label for this sub-agent node.",
                                              "type": "string"
                                            },
                                            "agentId": {
                                              "description": "The ID of the sub-agent to invoke.",
                                              "type": "string"
                                            },
                                            "instructions": {
                                              "description": "Optional instructions message prepended to the sub-agent conversation. Supports Handlebars interpolation against the parent execution scope: `{{var}}` reads workflow vars, `{{context.x}}` reads contextVars, `{{env.X}}` reads environment, `{{input.text}}` reads the original user input, and `{{nodes.<id>.<path>}}` reads prior node outputs.",
                                              "type": "string"
                                            },
                                            "transition": {
                                              "description": "Optional transitions to continue the flow after the sub-agent returns.",
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "if": {
                                                    "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                    "$ref": "#/components/schemas/exportAgent_schema0"
                                                  },
                                                  "default": {
                                                    "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                    "type": "boolean"
                                                  },
                                                  "to": {
                                                    "type": "object",
                                                    "properties": {
                                                      "nodeId": {
                                                        "description": "The ID of the target node to transition to.",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "nodeId"
                                                    ],
                                                    "additionalProperties": false
                                                  },
                                                  "stop": {
                                                    "description": "If true, stop execution after this transition.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "to"
                                                ],
                                                "additionalProperties": false
                                              }
                                            }
                                          },
                                          "required": [
                                            "id",
                                            "type",
                                            "agentId"
                                          ],
                                          "additionalProperties": false
                                        },
                                        {
                                          "type": "object",
                                          "properties": {
                                            "id": {
                                              "description": "Unique identifier for this node.",
                                              "type": "string"
                                            },
                                            "type": {
                                              "type": "string",
                                              "const": "end"
                                            },
                                            "label": {
                                              "description": "Human-readable label for this end node.",
                                              "type": "string"
                                            },
                                            "config": {
                                              "description": "Optional configuration for the end node behavior.",
                                              "type": "object",
                                              "properties": {
                                                "resetConversationHistory": {
                                                  "description": "If true, the next user message starts a new conversation with no prior history.",
                                                  "type": "boolean"
                                                }
                                              },
                                              "additionalProperties": false
                                            }
                                          },
                                          "required": [
                                            "id",
                                            "type"
                                          ],
                                          "additionalProperties": false
                                        },
                                        {
                                          "type": "object",
                                          "properties": {
                                            "id": {
                                              "description": "Unique identifier for this node.",
                                              "type": "string"
                                            },
                                            "type": {
                                              "type": "string",
                                              "const": "state"
                                            },
                                            "label": {
                                              "description": "Human-readable label for this state node.",
                                              "type": "string"
                                            },
                                            "outputVar": {
                                              "description": "Agent-scope get only: variable name that receives the value stored under `config.key` (null when the key has never been written). Downstream templates read it as `{{<outputVar>}}`; transition conditions as `{source:\"vars\", path:\"<outputVar>...\"}`.",
                                              "type": "string"
                                            },
                                            "config": {
                                              "type": "object",
                                              "properties": {
                                                "scope": {
                                                  "description": "How long the data lives and who sees it. execution: this run only. session: this conversation (thread) — a NEW conversation starts empty. agent: durable memory shared by every execution of this agent, across conversations — use it to remember things between independent runs. Survives clearCache.",
                                                  "type": "string",
                                                  "enum": [
                                                    "execution",
                                                    "session",
                                                    "agent"
                                                  ]
                                                },
                                                "operation": {
                                                  "description": "Agent scope only (default set). set: durably store the `state` entries. get: read the entry under `key` into `outputVar`. Execution/session scopes are always set — their values are injected into templates automatically, so no get is needed.",
                                                  "type": "string",
                                                  "enum": [
                                                    "set",
                                                    "get"
                                                  ]
                                                },
                                                "key": {
                                                  "description": "Agent-scope get: the memory key to read. Supports Handlebars (e.g. \"evidence-{{context.cnpj}}\") so one node can address per-entity entries. Rendered keys are limited to 512 characters.",
                                                  "type": "string"
                                                },
                                                "state": {
                                                  "description": "Key-value pairs to set (required for set operations). String values support Handlebars. In agent scope the KEYS are templates too (e.g. \"evidence-{{context.cnpj}}\"), each entry is stored as its own durable row, and serialized values are size-capped.",
                                                  "type": "object",
                                                  "propertyNames": {
                                                    "type": "string"
                                                  },
                                                  "additionalProperties": {}
                                                }
                                              },
                                              "required": [
                                                "scope"
                                              ],
                                              "additionalProperties": false
                                            },
                                            "transition": {
                                              "description": "Optional transitions to continue the flow after setting state.",
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "if": {
                                                    "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                    "$ref": "#/components/schemas/exportAgent_schema0"
                                                  },
                                                  "default": {
                                                    "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                    "type": "boolean"
                                                  },
                                                  "to": {
                                                    "type": "object",
                                                    "properties": {
                                                      "nodeId": {
                                                        "description": "The ID of the target node to transition to.",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "nodeId"
                                                    ],
                                                    "additionalProperties": false
                                                  },
                                                  "stop": {
                                                    "description": "If true, stop execution after this transition.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "to"
                                                ],
                                                "additionalProperties": false
                                              }
                                            }
                                          },
                                          "required": [
                                            "id",
                                            "type",
                                            "config"
                                          ],
                                          "additionalProperties": false
                                        },
                                        {
                                          "type": "object",
                                          "properties": {
                                            "id": {
                                              "description": "Unique identifier for this node.",
                                              "type": "string"
                                            },
                                            "type": {
                                              "type": "string",
                                              "const": "hub"
                                            },
                                            "label": {
                                              "description": "Human-readable label for this hub node.",
                                              "type": "string"
                                            },
                                            "transition": {
                                              "description": "Transitions to route connections to other nodes.",
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "if": {
                                                    "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                    "$ref": "#/components/schemas/exportAgent_schema0"
                                                  },
                                                  "default": {
                                                    "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                    "type": "boolean"
                                                  },
                                                  "to": {
                                                    "type": "object",
                                                    "properties": {
                                                      "nodeId": {
                                                        "description": "The ID of the target node to transition to.",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "nodeId"
                                                    ],
                                                    "additionalProperties": false
                                                  },
                                                  "stop": {
                                                    "description": "If true, stop execution after this transition.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "to"
                                                ],
                                                "additionalProperties": false
                                              }
                                            }
                                          },
                                          "required": [
                                            "id",
                                            "type"
                                          ],
                                          "additionalProperties": false
                                        },
                                        {
                                          "type": "object",
                                          "properties": {
                                            "id": {
                                              "description": "Unique identifier for this node.",
                                              "type": "string"
                                            },
                                            "type": {
                                              "type": "string",
                                              "const": "jump"
                                            },
                                            "label": {
                                              "description": "Human-readable label for this jump node.",
                                              "type": "string"
                                            },
                                            "transition": {
                                              "description": "Target node to jump to unconditionally.",
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "if": {
                                                    "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                    "$ref": "#/components/schemas/exportAgent_schema0"
                                                  },
                                                  "default": {
                                                    "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                    "type": "boolean"
                                                  },
                                                  "to": {
                                                    "type": "object",
                                                    "properties": {
                                                      "nodeId": {
                                                        "description": "The ID of the target node to transition to.",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "nodeId"
                                                    ],
                                                    "additionalProperties": false
                                                  },
                                                  "stop": {
                                                    "description": "If true, stop execution after this transition.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "to"
                                                ],
                                                "additionalProperties": false
                                              }
                                            }
                                          },
                                          "required": [
                                            "id",
                                            "type"
                                          ],
                                          "additionalProperties": false
                                        },
                                        {
                                          "type": "object",
                                          "properties": {
                                            "id": {
                                              "description": "Unique identifier for this node.",
                                              "type": "string"
                                            },
                                            "type": {
                                              "type": "string",
                                              "const": "clearCache"
                                            },
                                            "label": {
                                              "description": "Human-readable label for this clear cache node.",
                                              "type": "string"
                                            },
                                            "config": {
                                              "description": "Optional configuration controlling what is cleared.",
                                              "type": "object",
                                              "properties": {
                                                "clearScope": {
                                                  "description": "What to clear. executionCache (default): clears only the decision result cache. all: clears the entire session state including user-defined session variables.",
                                                  "type": "string",
                                                  "enum": [
                                                    "executionCache",
                                                    "all"
                                                  ]
                                                }
                                              },
                                              "additionalProperties": false
                                            },
                                            "transition": {
                                              "description": "Optional transitions to continue the flow after clearing cache.",
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "if": {
                                                    "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                    "$ref": "#/components/schemas/exportAgent_schema0"
                                                  },
                                                  "default": {
                                                    "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                    "type": "boolean"
                                                  },
                                                  "to": {
                                                    "type": "object",
                                                    "properties": {
                                                      "nodeId": {
                                                        "description": "The ID of the target node to transition to.",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "nodeId"
                                                    ],
                                                    "additionalProperties": false
                                                  },
                                                  "stop": {
                                                    "description": "If true, stop execution after this transition.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "to"
                                                ],
                                                "additionalProperties": false
                                              }
                                            }
                                          },
                                          "required": [
                                            "id",
                                            "type"
                                          ],
                                          "additionalProperties": false
                                        },
                                        {
                                          "type": "object",
                                          "properties": {
                                            "id": {
                                              "description": "Unique identifier for this node.",
                                              "type": "string"
                                            },
                                            "type": {
                                              "type": "string",
                                              "const": "javascript"
                                            },
                                            "label": {
                                              "description": "Human-readable label for this JavaScript node.",
                                              "type": "string"
                                            },
                                            "outputVar": {
                                              "description": "Variable name to store the returned value for downstream nodes. Downstream templates read it as `{{<outputVar>}}`; transition conditions as `{source:\"vars\", path:\"<outputVar>...\"}`.",
                                              "type": "string"
                                            },
                                            "config": {
                                              "type": "object",
                                              "properties": {
                                                "code": {
                                                  "description": "JavaScript source executed in a sandboxed QuickJS interpreter. Written as a function body: it receives ({ vars, evaluation, context, env, input, nodes }) and must `return` a JSON-serializable value. Synchronous only — no network, filesystem, require/import, or timers.",
                                                  "type": "string"
                                                },
                                                "timeoutMs": {
                                                  "description": "CPU deadline in milliseconds. Default 1000, max 10000.",
                                                  "type": "integer",
                                                  "minimum": 1,
                                                  "maximum": 10000
                                                }
                                              },
                                              "required": [
                                                "code"
                                              ],
                                              "additionalProperties": false
                                            },
                                            "transition": {
                                              "description": "Optional transitions to continue the flow after the code runs.",
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "if": {
                                                    "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                    "$ref": "#/components/schemas/exportAgent_schema0"
                                                  },
                                                  "default": {
                                                    "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                    "type": "boolean"
                                                  },
                                                  "to": {
                                                    "type": "object",
                                                    "properties": {
                                                      "nodeId": {
                                                        "description": "The ID of the target node to transition to.",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "nodeId"
                                                    ],
                                                    "additionalProperties": false
                                                  },
                                                  "stop": {
                                                    "description": "If true, stop execution after this transition.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "to"
                                                ],
                                                "additionalProperties": false
                                              }
                                            }
                                          },
                                          "required": [
                                            "id",
                                            "type",
                                            "config"
                                          ],
                                          "additionalProperties": false
                                        },
                                        {
                                          "type": "object",
                                          "properties": {
                                            "id": {
                                              "description": "Unique identifier for this node.",
                                              "type": "string"
                                            },
                                            "type": {
                                              "type": "string",
                                              "const": "forEach"
                                            },
                                            "label": {
                                              "description": "Human-readable label for this forEach node.",
                                              "type": "string"
                                            },
                                            "over": {
                                              "description": "Dotted path to the array to iterate, resolved against the execution scope: top-level workflow vars plus the \"context.\", \"env.\", \"input.\" and \"nodes.\" namespaces — for example \"research.socioAlvos\" or \"nodes.build_plan.result.targets\". This is a VALUE PATH, not a Handlebars template: Handlebars renders to a string, so an array passed through it would arrive as \"[object Object]\". A path wrapped in {{ }} is accepted and unwrapped. If the path does not resolve to an array the node fails loudly instead of iterating a string.",
                                              "type": "string"
                                            },
                                            "as": {
                                              "description": "Variable name bound to the current element inside the body node: \"socio\" makes {{socio.nome}} available to the body's templates. Must not be \"iteration\", which is reserved for the {index, total} binding also exposed to the body.",
                                              "type": "string"
                                            },
                                            "each": {
                                              "description": "The body node, referenced by ID. Must be an action, javascript or subAgent node declared in workflow.nodes with no other incoming transitions, and must not be an entry point. Its own \"transition\" array is ignored — the forEach node owns what happens after every item finishes. decision nodes are rejected because the execution cache is keyed by node ID, so parallel instances would contend for one cache entry.",
                                              "type": "object",
                                              "properties": {
                                                "nodeId": {
                                                  "description": "The ID of the node to run once per item.",
                                                  "type": "string"
                                                }
                                              },
                                              "required": [
                                                "nodeId"
                                              ],
                                              "additionalProperties": false
                                            },
                                            "collectInto": {
                                              "description": "Variable name receiving the per-item results array. Each entry is {index, item, ok, value?, grounding?, error?, errorName?}, where \"value\" is whatever the body node's own outputVar would have held (undefined when the body declares none) and \"grounding\" is that item's Google Search queries and sources when the body is a grounded INSTRUCTIONS node — the same shape a standalone node exposes as nodes.<id>.grounding. Entries stay aligned with the source array by index, including failed items, so a downstream node can tell \"this item returned nothing\" apart from \"this item was never tried\". Omit only if nothing downstream needs the results.",
                                              "type": "string"
                                            },
                                            "maxConcurrency": {
                                              "description": "How many items run at once. Defaults to 5. Raise carefully: per-item parallelism hits provider rate limits well before it hits platform limits.",
                                              "type": "integer",
                                              "minimum": 1,
                                              "maximum": 20
                                            },
                                            "transition": {
                                              "description": "Transitions to continue the flow after every item has finished.",
                                              "type": "array",
                                              "items": {
                                                "type": "object",
                                                "properties": {
                                                  "if": {
                                                    "description": "Optional condition that must be met for this transition to execute. On a decision node with multiple outgoing transitions, this should almost always be populated: the executor fires every unconditional transition in parallel regardless of which conditional transitions matched, so two or more bare transitions on a decision node create parallel fan-out, not routing. For a \"when nothing else matched\" fallback, use \"default\": true instead of a bare transition.",
                                                    "$ref": "#/components/schemas/exportAgent_schema0"
                                                  },
                                                  "default": {
                                                    "description": "If true, this transition is the node's default path: it fires only when NO conditional (\"if\") transition on the node matched. Mutually exclusive with \"if\" (a default transition must not have one). Unlike a bare transition — which ALWAYS fires, in parallel with everything else — a default transition is a true fallback, the routing equivalent of a switch statement's default case (or a BPMN default flow). Works on any node type; on decision nodes it also covers criteria skipped by contextual selection (their scores are absent, so conditions on them cannot match).",
                                                    "type": "boolean"
                                                  },
                                                  "to": {
                                                    "type": "object",
                                                    "properties": {
                                                      "nodeId": {
                                                        "description": "The ID of the target node to transition to.",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "required": [
                                                      "nodeId"
                                                    ],
                                                    "additionalProperties": false
                                                  },
                                                  "stop": {
                                                    "description": "If true, stop execution after this transition.",
                                                    "type": "boolean"
                                                  }
                                                },
                                                "required": [
                                                  "to"
                                                ],
                                                "additionalProperties": false
                                              }
                                            }
                                          },
                                          "required": [
                                            "id",
                                            "type",
                                            "over",
                                            "as",
                                            "each"
                                          ],
                                          "additionalProperties": false
                                        }
                                      ]
                                    }
                                  }
                                },
                                "required": [
                                  "toolName",
                                  "toolDescription",
                                  "entryPoints",
                                  "nodes"
                                ],
                                "additionalProperties": false
                              },
                              "tools": {
                                "deprecated": true,
                                "description": "Deprecated and ignored. Tool availability is configured by the application, not the agent spec.",
                                "type": "array",
                                "items": {}
                              },
                              "metadata": {
                                "description": "Arbitrary metadata for custom extensions. Not used by the execution engine.",
                                "type": "object",
                                "propertyNames": {
                                  "type": "string"
                                },
                                "additionalProperties": {}
                              }
                            },
                            "required": [
                              "version",
                              "name",
                              "prompt",
                              "workflow"
                            ],
                            "additionalProperties": false
                          },
                          "evals": {
                            "description": "The evaluation test cases exported with the agent.",
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "name": {
                                  "type": "string",
                                  "minLength": 1
                                },
                                "description": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                },
                                "scheduler": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                },
                                "evalSpec": {},
                                "enabled": {
                                  "type": "boolean"
                                },
                                "selfImproveEnabled": {
                                  "type": "boolean"
                                },
                                "selfImproveTargetScore": {
                                  "anyOf": [
                                    {
                                      "type": "number"
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                },
                                "selfImproveMaxIterations": {
                                  "type": "integer",
                                  "minimum": -9007199254740991,
                                  "maximum": 9007199254740991
                                },
                                "folderPath": {
                                  "description": "Materialized '/'-separated folder path of the eval (e.g. 'Regressão/Checkout'), or null for root.",
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                },
                                "tags": {
                                  "description": "Free-form labels of the eval.",
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "metadata": {
                                  "description": "Free-form data of the eval, including the `sources` conversations it was built from.",
                                  "anyOf": [
                                    {
                                      "description": "Free-form data recorded on the eval. Provenance belongs under `sources`, a list whose entries have documented keys so every writer points at the originating conversations the same way. An eval drawn from a single conversation carries a one-element list.",
                                      "type": "object",
                                      "properties": {
                                        "sources": {
                                          "description": "The conversations the eval was built from, most relevant first.",
                                          "maxItems": 25,
                                          "type": "array",
                                          "items": {
                                            "type": "object",
                                            "properties": {
                                              "threadId": {
                                                "description": "Id of the thread the eval was built from.",
                                                "examples": [
                                                  "cmc3k5r2b0004l608w1t8fmz9"
                                                ],
                                                "type": "string",
                                                "minLength": 1,
                                                "maxLength": 255
                                              },
                                              "executionId": {
                                                "description": "Id of the agent execution the eval was built from.",
                                                "examples": [
                                                  "exec_01j9z3k2b4c5"
                                                ],
                                                "type": "string",
                                                "minLength": 1,
                                                "maxLength": 255
                                              },
                                              "messageId": {
                                                "description": "Id of the specific message the eval was built from.",
                                                "examples": [
                                                  "cmc3k9p7f0007"
                                                ],
                                                "type": "string",
                                                "minLength": 1,
                                                "maxLength": 255
                                              },
                                              "url": {
                                                "description": "Link to the source conversation. Must be an absolute http(s) URL.",
                                                "examples": [
                                                  "https://platform.docana.com/application/42/agents/a1/logs?search=thread-1"
                                                ],
                                                "type": "string",
                                                "minLength": 1,
                                                "maxLength": 2048
                                              },
                                              "label": {
                                                "description": "Human friendly name of the source conversation.",
                                                "examples": [
                                                  "WhatsApp 5511 — 12/08"
                                                ],
                                                "type": "string",
                                                "minLength": 1,
                                                "maxLength": 255
                                              },
                                              "capturedAt": {
                                                "description": "ISO 8601 timestamp of when the eval was captured.",
                                                "examples": [
                                                  "2026-08-17T12:00:00.000Z"
                                                ],
                                                "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))$"
                                              }
                                            },
                                            "additionalProperties": {}
                                          }
                                        }
                                      },
                                      "additionalProperties": {}
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                }
                              },
                              "required": [
                                "name",
                                "evalSpec"
                              ],
                              "additionalProperties": false
                            }
                          },
                          "routines": {
                            "description": "The routines exported with the agent, including their triggers. API trigger tokens are never exported.",
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "name": {
                                  "type": "string",
                                  "minLength": 1
                                },
                                "prompt": {
                                  "type": "string"
                                },
                                "enabled": {
                                  "default": true,
                                  "type": "boolean"
                                },
                                "metadata": {
                                  "anyOf": [
                                    {
                                      "type": "object",
                                      "propertyNames": {
                                        "type": "string"
                                      },
                                      "additionalProperties": {}
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                },
                                "triggers": {
                                  "default": [],
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "enum": [
                                          "SCHEDULED",
                                          "API",
                                          "DOCUMENT_EVENT"
                                        ]
                                      },
                                      "enabled": {
                                        "default": true,
                                        "type": "boolean"
                                      },
                                      "cronExpression": {
                                        "anyOf": [
                                          {
                                            "type": "string"
                                          },
                                          {
                                            "type": "null"
                                          }
                                        ]
                                      },
                                      "collectionIds": {
                                        "default": [],
                                        "type": "array",
                                        "items": {
                                          "type": "integer",
                                          "minimum": -9007199254740991,
                                          "maximum": 9007199254740991
                                        }
                                      },
                                      "eventName": {
                                        "anyOf": [
                                          {
                                            "type": "string"
                                          },
                                          {
                                            "type": "null"
                                          }
                                        ]
                                      },
                                      "metadata": {
                                        "type": "object",
                                        "propertyNames": {
                                          "type": "string"
                                        },
                                        "additionalProperties": {}
                                      }
                                    },
                                    "required": [
                                      "type",
                                      "enabled",
                                      "collectionIds"
                                    ],
                                    "additionalProperties": false
                                  }
                                }
                              },
                              "required": [
                                "name",
                                "prompt",
                                "enabled",
                                "triggers"
                              ],
                              "additionalProperties": false
                            }
                          },
                          "insights": {
                            "description": "Per-agent Conversation Insights config. On import, `null` clears the config on the target agent and an absent field leaves it untouched.",
                            "anyOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "enabled": {
                                    "description": "Master kill switch for this agent's insights. When false, no extraction runs anywhere (the post-execution hook is suppressed and the archive API rejects summarize=true) and no prior insights are injected into new conversations.",
                                    "type": "boolean"
                                  },
                                  "shareWithPastConversations": {
                                    "description": "When true (and `enabled` is true), inject summaries from this user's past archived conversations in the same application into LLM calls that consume conversation history (instruction nodes; decision criteria with EvaluationParams.CONTEXT). Defaults to false.",
                                    "type": "boolean"
                                  },
                                  "summaryMode": {
                                    "description": "When to extract insights for this agent. \"afterExecution\" (default) runs archive + extraction after every successful agent turn (with or without an End node), so channels like WhatsApp keep producing insights. \"onArchive\" skips the automatic hook; insights are only extracted when the archive API is called with summarize=true.",
                                    "type": "string",
                                    "enum": [
                                      "afterExecution",
                                      "onArchive"
                                    ]
                                  },
                                  "summaryConfig": {
                                    "description": "Config used when this agent extracts a new summary (End-node generateInsights or archive API with summarize=true).",
                                    "type": "object",
                                    "properties": {
                                      "summaryLength": {
                                        "description": "Target length of the generated summary.",
                                        "type": "string",
                                        "enum": [
                                          "short",
                                          "medium",
                                          "detailed"
                                        ]
                                      },
                                      "customPrompt": {
                                        "description": "Optional extra guidance appended to the summarizer system prompt.",
                                        "type": "string"
                                      },
                                      "historyMessageLimit": {
                                        "description": "Cap on the number of recent messages included when generating the summary. Omitted = no cap.",
                                        "type": "integer",
                                        "exclusiveMinimum": 0,
                                        "maximum": 9007199254740991
                                      },
                                      "maxSummaryChars": {
                                        "description": "Optional cap on the persisted summary length (characters).",
                                        "type": "integer",
                                        "exclusiveMinimum": 0,
                                        "maximum": 9007199254740991
                                      }
                                    },
                                    "additionalProperties": false
                                  },
                                  "frequency": {
                                    "description": "How often insights are extracted. \"onEnd\" (default) extracts once when the conversation is archived. \"everyTurn\" extracts after every message — the legacy behaviour, which costs roughly O(N^2) tokens over an N-turn conversation. When absent, the legacy `summaryMode` is used: \"afterExecution\" maps to \"everyTurn\", anything else maps to \"onEnd\". Any other stored value (e.g. a removed legacy mode) resolves to \"onEnd\", the cheap option.",
                                    "type": "string",
                                    "enum": [
                                      "onEnd",
                                      "everyTurn"
                                    ]
                                  },
                                  "samplingRate": {
                                    "description": "Share of conversations that produce insights automatically, 0..1. Defaults to 1 (all). The decision is a deterministic hash of (agentId, threadId), so a conversation is either sampled for its whole life or not at all. Explicit archive calls and on-demand generation always run regardless of this rate.",
                                    "type": "number",
                                    "minimum": 0,
                                    "maximum": 1
                                  },
                                  "dataPoints": {
                                    "description": "Structured data points to extract from the conversation when generating insights.",
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "description": "Stable identifier for the data point; reused across saves so snapshot history and aggregations stay correlated over time.",
                                          "type": "string"
                                        },
                                        "name": {
                                          "description": "Human-readable name of the data point (displayed in the UI).",
                                          "type": "string"
                                        },
                                        "description": {
                                          "description": "Instruction describing what this data point should capture from the conversation.",
                                          "type": "string"
                                        },
                                        "type": {
                                          "description": "The expected type of the extracted value.",
                                          "type": "string",
                                          "enum": [
                                            "string",
                                            "number",
                                            "boolean"
                                          ]
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "name",
                                        "description",
                                        "type"
                                      ],
                                      "additionalProperties": false
                                    }
                                  }
                                },
                                "required": [
                                  "enabled"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "null"
                              }
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "spec",
                          "evals",
                          "routines"
                        ],
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "exportVersion",
                    "agent",
                    "subAgents"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the agent",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/publish-history/": {
      "get": {
        "operationId": "getAgentPublishHistory",
        "summary": "Get when an agent’s spec versions went live",
        "tags": [
          "agents"
        ],
        "description": "Returns one entry per published spec version in the window, oldest first, ordered by when it went live — which is not version order, since a rollback republishes an older version. `stamped` is false when the instant is the version’s creation time rather than a recorded publish, which is the case for versions published before that stamp existed. `days` defaults to 30 and is capped at 90.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Scope the agent lookup to this application.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "description": "How many days back the history reaches. Defaults to 30 and is capped at 90; invalid values fall back to the default.",
            "schema": {
              "examples": [
                30
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The publishes of the agent in the window",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "publishes": {
                      "description": "The publishes in the window, ordered by when each version went live.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "version": {
                            "description": "The spec version that went live.",
                            "examples": [
                              12
                            ],
                            "type": "number"
                          },
                          "publishedAt": {
                            "description": "When the version became live.",
                            "examples": [
                              "2026-08-05T12:00:00.000Z"
                            ],
                            "type": "string"
                          },
                          "stamped": {
                            "description": "False when the instant is the version’s creation time rather than a recorded publish, which is the case for versions published before that stamp existed.",
                            "examples": [
                              true
                            ],
                            "type": "boolean"
                          },
                          "versionName": {
                            "description": "The name given at publish time, when there was one.",
                            "examples": [
                              "Retention rewrite"
                            ],
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          }
                        },
                        "required": [
                          "version",
                          "publishedAt",
                          "stamped",
                          "versionName"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "publishes"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/versions/": {
      "get": {
        "operationId": "listAgentSpecVersions",
        "summary": "List an agent's spec versions",
        "tags": [
          "agents"
        ],
        "description": "Returns one page of up to 50 versions of the agent's spec history, newest first, with the current and published version numbers. Page older versions with `before`. The version numbers are what `diffAgents` accepts as `version` on an `agentId` side, so this is how callers discover what to diff. Legacy agents without artifact-backed specs report `currentVersion: null` and no versions.",
        "x-docana-mcp-tool": true,
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent addressed by the path.",
            "schema": {
              "examples": [
                "cmc4v8xq10001l708h2vxk9d3"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "description": "Return the page of versions strictly older than this version number.",
            "schema": {
              "type": "integer",
              "minimum": 2,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The agent's spec version history page",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "agentId": {
                      "description": "The agent whose history this is.",
                      "type": "string"
                    },
                    "name": {
                      "description": "The agent name, when set.",
                      "type": "string"
                    },
                    "currentVersion": {
                      "description": "The latest spec version, or null for legacy agents without version history.",
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "publishedVersion": {
                      "description": "The published spec version, or null when never published.",
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "totalVersionCount": {
                      "description": "How many versions exist in total.",
                      "type": "number"
                    },
                    "versions": {
                      "description": "One page of up to 50 versions, newest first. Page older versions with `before`.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "version": {
                            "description": "The spec version number, usable as `version` in `diffAgents`.",
                            "type": "number"
                          },
                          "createdAt": {
                            "description": "When this version was created (ISO-8601).",
                            "type": "string"
                          },
                          "author": {
                            "description": "Who saved this version, when known.",
                            "type": "object",
                            "properties": {
                              "name": {
                                "description": "Display name of the user who saved this version.",
                                "type": "string"
                              },
                              "email": {
                                "description": "Email of the user who saved this version.",
                                "type": "string"
                              }
                            },
                            "additionalProperties": false
                          }
                        },
                        "required": [
                          "version",
                          "createdAt"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "agentId",
                    "currentVersion",
                    "publishedVersion",
                    "totalVersionCount",
                    "versions"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the agent",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/publish/": {
      "post": {
        "operationId": "publishAgent",
        "summary": "Publish the latest saved agent spec",
        "tags": [
          "agents"
        ],
        "description": "Equivalent to the UI Publish action. Explicitly call after create or update to promote the latest linked draft. It resolves inline criteria and rejects invalid AgentSpec V2/template defects. applicationId is the recommended scope and must exactly match the agent. For backwards compatibility, callers that omit it use the active agent’s application and receive deprecation headers. Legacy artifactId must match the linked draft; version is only a stale-client hint.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent addressed by the path.",
            "schema": {
              "examples": [
                "cmc4v8xq10001l708h2vxk9d3"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Recommended application scope plus optional version metadata and legacy compatibility hints. Omitting applicationId is deprecated compatibility behavior.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "applicationId": {
                    "description": "Recommended application containing the agent. Omit only for deprecated backwards compatibility: the server infers it from the active agent and includes deprecation response headers.",
                    "examples": [
                      42
                    ],
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  "name": {
                    "description": "Display name for the published version.",
                    "examples": [
                      "Pricing update"
                    ],
                    "type": "string"
                  },
                  "description": {
                    "description": "Description of what changed in this version.",
                    "examples": [
                      "Updates the pricing answers and the discount escalation flow."
                    ],
                    "type": "string"
                  },
                  "artifactId": {
                    "description": "Legacy compatibility hint. Must equal the agent-linked draft artifact.",
                    "type": "string"
                  },
                  "version": {
                    "description": "Legacy stale-client hint. The latest linked draft version is always published.",
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The published (or already published) version",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "Always true on a 200 response.",
                      "type": "boolean"
                    },
                    "alreadyPublished": {
                      "description": "True when the latest saved spec was already the published version and nothing changed.",
                      "type": "boolean"
                    },
                    "changed": {
                      "description": "False when this request was an idempotent no-op.",
                      "type": "boolean"
                    },
                    "publishedArtifactId": {
                      "description": "Id of the spec artifact that now serves as the published version.",
                      "examples": [
                        "k2mPq7xWn4RtYv0a"
                      ],
                      "type": "string"
                    },
                    "publishedVersion": {
                      "description": "Version number of the published spec artifact.",
                      "examples": [
                        3
                      ],
                      "type": "number"
                    }
                  },
                  "required": [
                    "success",
                    "alreadyPublished",
                    "publishedArtifactId",
                    "publishedVersion"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid legacy artifact hint or invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Agent or linked draft not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "409": {
            "description": "Agent has no saved spec artifact yet",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "422": {
            "description": "The latest spec is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/metadata/": {
      "patch": {
        "operationId": "updateAgentMetadata",
        "summary": "Update agent thread metadata",
        "tags": [
          "agents"
        ],
        "description": "Updates `specThreadId` and/or `sandboxThreadId` in the agent metadata. Fields set to `null` are cleared; omitted fields are left untouched.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent addressed by the path.",
            "schema": {
              "examples": [
                "cmc4v8xq10001l708h2vxk9d3"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "The thread ids to set or clear. An empty body is valid and changes nothing.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "specThreadId": {
                    "description": "Id of the AI builder chat thread linked to the agent spec. Pass `null` to clear the link, omit the field to leave it unchanged.",
                    "examples": [
                      "cmc5t1r8e0003l708p4wqz6m1"
                    ],
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "sandboxThreadId": {
                    "description": "Id of the sandbox chat thread linked to the agent. Pass `null` to clear the link, omit the field to leave it unchanged.",
                    "examples": [
                      "cmc5t2k9f0004l708d8yrn2q7"
                    ],
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The agent id and its updated metadata",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "Id of the updated agent.",
                      "examples": [
                        "cmc4v8xq10001l708h2vxk9d3"
                      ],
                      "type": "string"
                    },
                    "metadata": {
                      "description": "The agent's full metadata object after the update."
                    }
                  },
                  "required": [
                    "id",
                    "metadata"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or agent without application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/sandbox/": {
      "post": {
        "operationId": "runAgentSandbox",
        "summary": "Run an agent in sandbox mode",
        "tags": [
          "agents"
        ],
        "description": "Streams an AI-SDK UI-message response of a sandbox agent run, including node lifecycle events and trace data. Body: `{ messages?, assistantContext: { applicationId, ... }, data? }`.",
        "x-docana-streaming": true,
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent addressed by the path.",
            "schema": {
              "examples": [
                "cmc4v8xq10001l708h2vxk9d3"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "The conversation and context for the sandbox run.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "messages": {
                    "description": "The conversation so far. When omitted or null, the conversation starts empty.",
                    "type": "array",
                    "items": {
                      "description": "A conversation message in the AI SDK UI-message format.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "Unique id of the message within the conversation.",
                          "examples": [
                            "msg-4fT7aQ"
                          ],
                          "type": "string"
                        },
                        "role": {
                          "description": "Author of the message.",
                          "examples": [
                            "user"
                          ],
                          "type": "string",
                          "enum": [
                            "system",
                            "user",
                            "assistant"
                          ]
                        },
                        "parts": {
                          "description": "Ordered content parts of the message.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "type": {
                                "description": "Kind of the part, for example `text`.",
                                "examples": [
                                  "text"
                                ],
                                "type": "string"
                              },
                              "text": {
                                "description": "Text content. Present on `text` parts.",
                                "type": "string"
                              }
                            },
                            "required": [
                              "type"
                            ],
                            "additionalProperties": {}
                          }
                        }
                      },
                      "required": [
                        "id",
                        "role",
                        "parts"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "assistantContext": {
                    "description": "Context of the run. Additional fields such as `collectionIds`, `documentIds` or `interactionId` are passed through to the run.",
                    "type": "object",
                    "properties": {
                      "applicationId": {
                        "description": "Id of the application the run is scoped to. Required.",
                        "examples": [
                          42
                        ],
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "threadId": {
                        "description": "Id of an existing thread to continue. A new thread is created when omitted.",
                        "examples": [
                          "cmc5t2k9f0004l708d8yrn2q7"
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "applicationId"
                    ],
                    "additionalProperties": {}
                  },
                  "data": {
                    "description": "Extra flags for the stream.",
                    "type": "object",
                    "properties": {
                      "audioEnabled": {
                        "description": "When true, the response stream also carries synthesized speech for the assistant reply.",
                        "type": "boolean"
                      }
                    },
                    "additionalProperties": {}
                  }
                },
                "required": [
                  "assistantContext"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "UI-message event stream with the sandbox run"
          },
          "400": {
            "description": "Missing applicationId",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/execute/": {
      "post": {
        "operationId": "executeAgent",
        "summary": "Execute a published agent asynchronously",
        "tags": [
          "agents"
        ],
        "description": "Validates the request, schedules a background run of the published agent version and returns immediately with both the `executionId` and `assistantMessageId` handles the run will use. Output content is populated asynchronously. Body: `{ prompt: string, threadId?: string, context?: object, waitSeconds?: number }`. Poll `getAgentExecution` with the returned id for status, node outputs and the threadId; the execution row appears once the background run starts, so a brief 404 right after scheduling means \"not started yet\" while a persistent one means the run failed to start. Optional bounded wait: `waitSeconds` (1-120) holds the response until the run settles or the window elapses; the response then carries `waitOutcome` (`completed`, `failed` or `timeout`) and, when the run settled, `executionStatus`. A timeout never cancels the run — keep polling `getAgentExecution` with the same `executionId`. Supports the `Idempotency-Key` header: a retry with the same key and body replays the stored ack (same executionId) instead of running the agent a second time. `waitSeconds` is a delivery preference, not part of the request identity: it is excluded from the idempotency payload hash, and replays return the stored asynchronous ack immediately without waiting.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent addressed by the path.",
            "schema": {
              "examples": [
                "cmc4v8xq10001l708h2vxk9d3"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "The prompt to run the agent on, with an optional thread, runtime context and bounded wait.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompt": {
                    "description": "The user message the agent runs on.",
                    "examples": [
                      "Summarize the open support tickets for Acme Corp."
                    ],
                    "type": "string"
                  },
                  "threadId": {
                    "description": "Id of an existing thread to continue. A new thread is created when omitted.",
                    "examples": [
                      "cmc5t2k9f0004l708d8yrn2q7"
                    ],
                    "type": "string"
                  },
                  "context": {
                    "description": "Runtime context variables made available to the agent workflow, for example channel or account metadata.",
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {}
                  },
                  "waitSeconds": {
                    "description": "Opt-in bounded wait: hold the response until the run settles or this many seconds elapse (max 120). Omit for the asynchronous default. A timeout never cancels the run — poll getAgentExecution with the returned executionId. Excluded from the Idempotency-Key payload hash, and ignored on replays.",
                    "examples": [
                      30
                    ],
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 120
                  }
                },
                "required": [
                  "prompt"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The run was scheduled",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Acknowledgement of the dispatch. By default the agent runs asynchronously after this response is sent; with `waitSeconds` the response also reports how the bounded wait ended.",
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the background run was scheduled.",
                      "type": "boolean"
                    },
                    "executionId": {
                      "description": "The id the scheduled run creates its AgentExecution under. Poll getAgentExecution with it for status, node outputs and the threadId (the row appears once the run starts).",
                      "type": "string"
                    },
                    "assistantMessageId": {
                      "description": "ID of the assistant output message created for this execution. Its content is populated asynchronously; use it with executionId to follow the run.",
                      "type": "string"
                    },
                    "waitOutcome": {
                      "description": "Present only when the request opted into `waitSeconds`. `completed`: the run settled within the window (see executionStatus). `failed`: the run settled with an internal error; poll getAgentExecution for detail. `timeout`: the window elapsed while the run keeps going — a timeout never cancels the execution, keep polling getAgentExecution with the same executionId.",
                      "type": "string",
                      "enum": [
                        "completed",
                        "failed",
                        "timeout"
                      ]
                    },
                    "executionStatus": {
                      "description": "AgentExecution row status observed after a waited run settled (absent on timeout, and when the run failed before creating its execution row). STOPPED means an explicit stop request ended it.",
                      "type": "string",
                      "enum": [
                        "RUNNING",
                        "FINISHED",
                        "STOPPED"
                      ]
                    }
                  },
                  "required": [
                    "success",
                    "executionId",
                    "assistantMessageId"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Missing prompt, invalid waitSeconds or agent without application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application or thread",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Agent or thread not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "409": {
            "description": "Agent not published, or Idempotency-Key conflict/in-progress",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/test-cases/": {
      "get": {
        "operationId": "listAgentTestCases",
        "summary": "List the test cases of an agent",
        "tags": [
          "agent-testing"
        ],
        "description": "Returns every test case of the agent, optionally narrowed to one application with `applicationId`. Each entry includes its full `evalSpec` document. Use `POST /api/v1/agents/{agentId}/test-cases/{testCaseId}/run/` to execute one of them.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application to scope the request to. Omit to use the company-wide scope.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The test cases of the agent",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "description": "The test case's unique id.",
                        "examples": [
                          "cmc3k5r2b0004l608w1t8fmz9"
                        ],
                        "type": "string"
                      },
                      "applicationId": {
                        "description": "Id of the application the test case is scoped to, or null for a company-wide test case.",
                        "examples": [
                          42
                        ],
                        "anyOf": [
                          {
                            "type": "number"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "agentId": {
                        "description": "Id of the agent the test case belongs to.",
                        "examples": [
                          "cmc3k1x9d0001l608r2vhq7e2"
                        ],
                        "type": "string"
                      },
                      "name": {
                        "description": "Human friendly name of the test case.",
                        "examples": [
                          "Order status happy path"
                        ],
                        "type": "string"
                      },
                      "description": {
                        "description": "Description of what the test case validates, or null.",
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "scheduler": {
                        "description": "Cron expression for scheduled runs, or null when the test case only runs manually.",
                        "examples": [
                          "0 6 * * *"
                        ],
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "evalSpec": {
                        "description": "The full evaluation specification JSON document: ordered user messages and assertion steps, plus optional runtime context variables and webhook node mocks."
                      },
                      "enabled": {
                        "description": "Whether the test case can run, on schedule or manually.",
                        "examples": [
                          true
                        ],
                        "type": "boolean"
                      },
                      "lastRunAt": {
                        "description": "ISO 8601 timestamp of the last run, or null when the test case never ran.",
                        "examples": [
                          "2026-07-01T12:30:00.000Z"
                        ],
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "selfImproveEnabled": {
                        "description": "Whether self-improvement is enabled for this test case.",
                        "examples": [
                          false
                        ],
                        "type": "boolean"
                      },
                      "selfImproveTargetScore": {
                        "description": "Score from 0 to 10 that self-improvement tries to reach, or null.",
                        "examples": [
                          8
                        ],
                        "anyOf": [
                          {
                            "type": "number"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "selfImproveMaxIterations": {
                        "description": "Maximum number of self-improvement iterations.",
                        "examples": [
                          10
                        ],
                        "type": "number"
                      },
                      "folderId": {
                        "description": "Id of the folder the test case lives in, or null for the root level.",
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "tags": {
                        "description": "Free-form labels of the test case.",
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "metadata": {
                        "description": "Free-form data about the test case, or null. `sources` holds its provenance: the threads, executions or messages it was built from.",
                        "anyOf": [
                          {
                            "description": "Free-form data recorded on the eval. Provenance belongs under `sources`, a list whose entries have documented keys so every writer points at the originating conversations the same way. An eval drawn from a single conversation carries a one-element list.",
                            "type": "object",
                            "properties": {
                              "sources": {
                                "description": "The conversations the eval was built from, most relevant first.",
                                "maxItems": 25,
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "threadId": {
                                      "description": "Id of the thread the eval was built from.",
                                      "examples": [
                                        "cmc3k5r2b0004l608w1t8fmz9"
                                      ],
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 255
                                    },
                                    "executionId": {
                                      "description": "Id of the agent execution the eval was built from.",
                                      "examples": [
                                        "exec_01j9z3k2b4c5"
                                      ],
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 255
                                    },
                                    "messageId": {
                                      "description": "Id of the specific message the eval was built from.",
                                      "examples": [
                                        "cmc3k9p7f0007"
                                      ],
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 255
                                    },
                                    "url": {
                                      "description": "Link to the source conversation. Must be an absolute http(s) URL.",
                                      "examples": [
                                        "https://platform.docana.com/application/42/agents/a1/logs?search=thread-1"
                                      ],
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 2048
                                    },
                                    "label": {
                                      "description": "Human friendly name of the source conversation.",
                                      "examples": [
                                        "WhatsApp 5511 — 12/08"
                                      ],
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 255
                                    },
                                    "capturedAt": {
                                      "description": "ISO 8601 timestamp of when the eval was captured.",
                                      "examples": [
                                        "2026-08-17T12:00:00.000Z"
                                      ],
                                      "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))$"
                                    }
                                  },
                                  "additionalProperties": {}
                                }
                              }
                            },
                            "additionalProperties": {}
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "createdAt": {
                        "description": "ISO 8601 creation timestamp.",
                        "examples": [
                          "2026-06-15T09:00:00.000Z"
                        ],
                        "type": "string"
                      },
                      "updatedAt": {
                        "description": "ISO 8601 timestamp of the last update.",
                        "examples": [
                          "2026-07-01T12:30:00.000Z"
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "id",
                      "applicationId",
                      "agentId",
                      "name",
                      "description",
                      "scheduler",
                      "evalSpec",
                      "enabled",
                      "lastRunAt",
                      "selfImproveEnabled",
                      "selfImproveTargetScore",
                      "selfImproveMaxIterations",
                      "createdAt",
                      "updatedAt"
                    ],
                    "additionalProperties": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createAgentTestCase",
        "summary": "Create a test case for an agent",
        "tags": [
          "agent-testing"
        ],
        "description": "The name must be unique within the agent. When `scheduler` is set and the test case is enabled, the platform also runs it automatically on that cron schedule. Trigger it on demand with `POST /api/v1/agents/{agentId}/test-cases/{testCaseId}/run/`. The application scope comes from `applicationId` in the body, or from the query string when the body omits it.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application to scope the request to. Omit to use the company-wide scope.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "applicationId": {
                    "description": "Id of the application the test case is scoped to. Required for a runnable test case.",
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  "name": {
                    "description": "Human friendly name of the test case. Must be unique within the agent.",
                    "examples": [
                      "Order status happy path"
                    ],
                    "type": "string",
                    "minLength": 1
                  },
                  "description": {
                    "description": "Optional description of what the test case validates.",
                    "examples": [
                      "Checks that the agent reports the delivery status for an order number."
                    ],
                    "type": "string"
                  },
                  "scheduler": {
                    "description": "Cron expression for scheduled automated runs. Omit to only run the test case manually.",
                    "examples": [
                      "0 6 * * *"
                    ],
                    "type": "string"
                  },
                  "enabled": {
                    "description": "Whether the test case can run, on schedule or manually. Defaults to true.",
                    "examples": [
                      true
                    ],
                    "type": "boolean"
                  },
                  "evalSpec": {
                    "description": "The evaluation specification: an ordered list of user messages and assertion steps, plus optional runtime context variables and webhook node mocks.",
                    "type": "object",
                    "properties": {
                      "context": {
                        "examples": [
                          {
                            "channel": "whatsapp",
                            "customerTier": "premium"
                          }
                        ],
                        "type": "object",
                        "propertyNames": {
                          "type": "string"
                        },
                        "additionalProperties": {
                          "$ref": "#/components/schemas/createAgentTestCase_schema0"
                        }
                      },
                      "repeats": {
                        "examples": [
                          3
                        ],
                        "default": 1,
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 10
                      },
                      "minPassRate": {
                        "examples": [
                          0.67
                        ],
                        "default": 1,
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1
                      },
                      "advisory": {
                        "examples": [
                          false
                        ],
                        "default": false,
                        "type": "boolean"
                      },
                      "nodeMocks": {
                        "examples": [
                          {
                            "node_order_lookup": {
                              "type": "webhook",
                              "mode": "staticResponse",
                              "response": {
                                "status": 200,
                                "body": {
                                  "orderStatus": "shipped"
                                }
                              }
                            }
                          }
                        ],
                        "type": "object",
                        "propertyNames": {
                          "type": "string"
                        },
                        "additionalProperties": {
                          "anyOf": [
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "examples": [
                                    "webhook"
                                  ],
                                  "type": "string",
                                  "const": "webhook"
                                },
                                "mode": {
                                  "default": "staticResponse",
                                  "type": "string",
                                  "const": "staticResponse"
                                },
                                "response": {
                                  "anyOf": [
                                    {
                                      "type": "object",
                                      "properties": {
                                        "status": {
                                          "examples": [
                                            200
                                          ],
                                          "type": "integer",
                                          "minimum": 100,
                                          "maximum": 599
                                        },
                                        "headers": {
                                          "examples": [
                                            {
                                              "content-type": "application/json"
                                            }
                                          ],
                                          "type": "object",
                                          "propertyNames": {
                                            "type": "string"
                                          },
                                          "additionalProperties": {
                                            "type": "string"
                                          }
                                        },
                                        "body": {
                                          "examples": [
                                            {
                                              "orderStatus": "shipped"
                                            }
                                          ],
                                          "$ref": "#/components/schemas/createAgentTestCase_schema0"
                                        },
                                        "noResponse": {
                                          "not": {}
                                        }
                                      },
                                      "required": [
                                        "status"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "noResponse": {
                                          "examples": [
                                            true
                                          ],
                                          "type": "boolean",
                                          "const": true
                                        },
                                        "error": {
                                          "examples": [
                                            "connect ECONNREFUSED 10.0.0.4:443"
                                          ],
                                          "type": "string"
                                        },
                                        "status": {
                                          "not": {}
                                        }
                                      },
                                      "required": [
                                        "noResponse"
                                      ]
                                    }
                                  ]
                                }
                              },
                              "required": [
                                "type",
                                "response"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "examples": [
                                    "webhook"
                                  ],
                                  "type": "string",
                                  "const": "webhook"
                                },
                                "mode": {
                                  "type": "string",
                                  "const": "sequence"
                                },
                                "responses": {
                                  "examples": [
                                    [
                                      {
                                        "status": 400,
                                        "body": {
                                          "error": "CEP inválido"
                                        }
                                      },
                                      {
                                        "status": 201,
                                        "body": {
                                          "data": {
                                            "status": "AUTORIZADA"
                                          }
                                        }
                                      }
                                    ]
                                  ],
                                  "minItems": 1,
                                  "type": "array",
                                  "items": {
                                    "anyOf": [
                                      {
                                        "type": "object",
                                        "properties": {
                                          "status": {
                                            "examples": [
                                              200
                                            ],
                                            "type": "integer",
                                            "minimum": 100,
                                            "maximum": 599
                                          },
                                          "headers": {
                                            "examples": [
                                              {
                                                "content-type": "application/json"
                                              }
                                            ],
                                            "type": "object",
                                            "propertyNames": {
                                              "type": "string"
                                            },
                                            "additionalProperties": {
                                              "type": "string"
                                            }
                                          },
                                          "body": {
                                            "examples": [
                                              {
                                                "orderStatus": "shipped"
                                              }
                                            ],
                                            "$ref": "#/components/schemas/createAgentTestCase_schema0"
                                          },
                                          "noResponse": {
                                            "not": {}
                                          }
                                        },
                                        "required": [
                                          "status"
                                        ]
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "noResponse": {
                                            "examples": [
                                              true
                                            ],
                                            "type": "boolean",
                                            "const": true
                                          },
                                          "error": {
                                            "examples": [
                                              "connect ECONNREFUSED 10.0.0.4:443"
                                            ],
                                            "type": "string"
                                          },
                                          "status": {
                                            "not": {}
                                          }
                                        },
                                        "required": [
                                          "noResponse"
                                        ]
                                      }
                                    ]
                                  }
                                }
                              },
                              "required": [
                                "type",
                                "mode",
                                "responses"
                              ]
                            }
                          ]
                        }
                      },
                      "steps": {
                        "examples": [
                          [
                            {
                              "type": "user",
                              "text": "Where is my order #4821?"
                            },
                            {
                              "type": "smartAssertion",
                              "expectedOutput": "The agent confirms order 4821 shipped and gives the delivery date.",
                              "minScore": 7
                            }
                          ]
                        ],
                        "minItems": 1,
                        "type": "array",
                        "items": {
                          "oneOf": [
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "examples": [
                                    "user"
                                  ],
                                  "type": "string",
                                  "const": "user"
                                },
                                "text": {
                                  "examples": [
                                    "Where is my order #4821?"
                                  ],
                                  "type": "string",
                                  "minLength": 1
                                },
                                "attachments": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "url": {
                                        "examples": [
                                          "https://cdn.example.com/receipts/order-4821.pdf"
                                        ],
                                        "type": "string"
                                      },
                                      "name": {
                                        "examples": [
                                          "order-4821.pdf"
                                        ],
                                        "type": "string"
                                      },
                                      "contentType": {
                                        "examples": [
                                          "application/pdf"
                                        ],
                                        "type": "string"
                                      }
                                    },
                                    "required": [
                                      "url"
                                    ]
                                  }
                                },
                                "delayMs": {
                                  "examples": [
                                    1000
                                  ],
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 60000
                                },
                                "waitFor": {
                                  "examples": [
                                    "none"
                                  ],
                                  "type": "string",
                                  "enum": [
                                    "settled",
                                    "none"
                                  ]
                                },
                                "injectAfterNode": {
                                  "examples": [
                                    "n-n1jtll0d9"
                                  ],
                                  "type": "string",
                                  "minLength": 1
                                }
                              },
                              "required": [
                                "type",
                                "text"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "evaluationSteps": {
                                  "examples": [
                                    [
                                      "Check the reply names order 4821",
                                      "Check the reply states the delivery status"
                                    ]
                                  ],
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "expectedOutput": {
                                  "examples": [
                                    "The agent confirms order 4821 shipped and gives the delivery date."
                                  ],
                                  "type": "string"
                                },
                                "minScore": {
                                  "default": 7,
                                  "type": "number",
                                  "minimum": 0,
                                  "maximum": 10
                                },
                                "evaluationCriteria": {
                                  "examples": [
                                    "The reply must mention the order number and the current status."
                                  ],
                                  "type": "string"
                                },
                                "nodeId": {
                                  "examples": [
                                    "monta_report"
                                  ],
                                  "type": "string"
                                },
                                "selector": {
                                  "default": "last",
                                  "type": "string",
                                  "enum": [
                                    "first",
                                    "last"
                                  ]
                                },
                                "source": {
                                  "default": "output",
                                  "type": "string",
                                  "enum": [
                                    "input",
                                    "output",
                                    "record"
                                  ]
                                },
                                "path": {
                                  "examples": [
                                    "result.findings"
                                  ],
                                  "type": "string",
                                  "minLength": 1
                                },
                                "type": {
                                  "examples": [
                                    "smartAssertion"
                                  ],
                                  "type": "string",
                                  "const": "smartAssertion"
                                }
                              },
                              "required": [
                                "type"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "examples": [
                                    "actionAssertion"
                                  ],
                                  "type": "string",
                                  "const": "actionAssertion"
                                },
                                "actionType": {
                                  "type": "string",
                                  "enum": [
                                    "INSTRUCTIONS",
                                    "EMAIL",
                                    "WEBHOOK"
                                  ]
                                },
                                "operator": {
                                  "type": "string",
                                  "enum": [
                                    "eq",
                                    "gt",
                                    "lt"
                                  ]
                                },
                                "count": {
                                  "examples": [
                                    1
                                  ],
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 9007199254740991
                                },
                                "actionId": {
                                  "examples": [
                                    "action_refund_webhook"
                                  ],
                                  "type": "string"
                                },
                                "atLeast": {
                                  "examples": [
                                    1
                                  ],
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 9007199254740991
                                },
                                "equals": {
                                  "examples": [
                                    1
                                  ],
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 9007199254740991
                                }
                              },
                              "required": [
                                "type"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "examples": [
                                    "nodeAssertion"
                                  ],
                                  "type": "string",
                                  "const": "nodeAssertion"
                                },
                                "label": {
                                  "examples": [
                                    "Order lookup ran once"
                                  ],
                                  "type": "string"
                                },
                                "nodeId": {
                                  "examples": [
                                    "node_order_lookup"
                                  ],
                                  "type": "string"
                                },
                                "nodeType": {
                                  "examples": [
                                    "subAgent"
                                  ],
                                  "type": "string",
                                  "enum": [
                                    "action",
                                    "decision",
                                    "subAgent",
                                    "end",
                                    "state",
                                    "hub",
                                    "jump",
                                    "clearCache",
                                    "javascript",
                                    "forEach"
                                  ]
                                },
                                "operator": {
                                  "default": "gte",
                                  "type": "string",
                                  "enum": [
                                    "eq",
                                    "gt",
                                    "gte",
                                    "lt",
                                    "lte"
                                  ]
                                },
                                "count": {
                                  "default": 1,
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 9007199254740991
                                },
                                "selector": {
                                  "default": "any",
                                  "type": "string",
                                  "enum": [
                                    "first",
                                    "last",
                                    "any"
                                  ]
                                },
                                "assertions": {
                                  "default": [],
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "source": {
                                        "default": "output",
                                        "type": "string",
                                        "enum": [
                                          "input",
                                          "output",
                                          "record"
                                        ]
                                      },
                                      "path": {
                                        "examples": [
                                          "order.status"
                                        ],
                                        "type": "string",
                                        "minLength": 1
                                      },
                                      "operator": {
                                        "default": "exists",
                                        "type": "string",
                                        "enum": [
                                          "exists",
                                          "eq",
                                          "neq",
                                          "contains",
                                          "notContains",
                                          "gt",
                                          "gte",
                                          "lt",
                                          "lte"
                                        ]
                                      },
                                      "value": {
                                        "examples": [
                                          "shipped"
                                        ],
                                        "$ref": "#/components/schemas/createAgentTestCase_schema0"
                                      },
                                      "label": {
                                        "examples": [
                                          "Order status is shipped"
                                        ],
                                        "type": "string"
                                      }
                                    },
                                    "required": [
                                      "path"
                                    ]
                                  }
                                }
                              },
                              "required": [
                                "type"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "examples": [
                                    "conversationAssertion"
                                  ],
                                  "type": "string",
                                  "const": "conversationAssertion"
                                },
                                "label": {
                                  "examples": [
                                    "Conversation never dies without a response"
                                  ],
                                  "type": "string"
                                },
                                "expectNoResponse": {
                                  "examples": [
                                    false
                                  ],
                                  "type": "boolean"
                                }
                              },
                              "required": [
                                "type",
                                "expectNoResponse"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "examples": [
                                    "assistant"
                                  ],
                                  "type": "string",
                                  "const": "assistant"
                                },
                                "text": {
                                  "examples": [
                                    "Seu pedido #123 saiu ontem e chega até sexta."
                                  ],
                                  "type": "string",
                                  "minLength": 1
                                }
                              },
                              "required": [
                                "type"
                              ]
                            }
                          ]
                        }
                      }
                    },
                    "required": [
                      "steps"
                    ]
                  },
                  "selfImproveEnabled": {
                    "description": "Whether self-improvement is enabled. When on, the platform runs the test, analyzes the scores, and iteratively refines the agent flow until the target score is reached.",
                    "examples": [
                      false
                    ],
                    "type": "boolean"
                  },
                  "selfImproveTargetScore": {
                    "description": "Score from 0 to 10 that self-improvement tries to reach.",
                    "examples": [
                      8
                    ],
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 10
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "selfImproveMaxIterations": {
                    "description": "Maximum number of self-improvement iterations, from 1 to 50.",
                    "examples": [
                      10
                    ],
                    "type": "number",
                    "minimum": 1,
                    "maximum": 50
                  },
                  "folderId": {
                    "description": "Id of the folder the test case lives in. Null or omitted means the root level.",
                    "examples": [
                      "cmc3k7f1a0002l608q9d2xk41"
                    ],
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "tags": {
                    "description": "Free-form labels for categorizing the test case. Trimmed and deduplicated server-side.",
                    "examples": [
                      [
                        "smoke",
                        "checkout"
                      ]
                    ],
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "metadata": {
                    "description": "Free-form data about the test case. Record where the test case came from under `sources` — the threads, executions or messages it was built from — so its origins can be traced back to the real conversations. A test case drawn from a single conversation carries a one-element list.",
                    "anyOf": [
                      {
                        "description": "Free-form data recorded on the eval. Provenance belongs under `sources`, a list whose entries have documented keys so every writer points at the originating conversations the same way. An eval drawn from a single conversation carries a one-element list.",
                        "type": "object",
                        "properties": {
                          "sources": {
                            "description": "The conversations the eval was built from, most relevant first.",
                            "maxItems": 25,
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "threadId": {
                                  "description": "Id of the thread the eval was built from.",
                                  "examples": [
                                    "cmc3k5r2b0004l608w1t8fmz9"
                                  ],
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 255
                                },
                                "executionId": {
                                  "description": "Id of the agent execution the eval was built from.",
                                  "examples": [
                                    "exec_01j9z3k2b4c5"
                                  ],
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 255
                                },
                                "messageId": {
                                  "description": "Id of the specific message the eval was built from.",
                                  "examples": [
                                    "cmc3k9p7f0007"
                                  ],
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 255
                                },
                                "url": {
                                  "description": "Link to the source conversation. Must be an absolute http(s) URL.",
                                  "examples": [
                                    "https://platform.docana.com/application/42/agents/a1/logs?search=thread-1"
                                  ],
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 2048
                                },
                                "label": {
                                  "description": "Human friendly name of the source conversation.",
                                  "examples": [
                                    "WhatsApp 5511 — 12/08"
                                  ],
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 255
                                },
                                "capturedAt": {
                                  "description": "ISO 8601 timestamp of when the eval was captured.",
                                  "examples": [
                                    "2026-08-17T12:00:00.000Z"
                                  ],
                                  "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))$"
                                }
                              },
                              "additionalProperties": {}
                            }
                          }
                        },
                        "additionalProperties": {}
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "required": [
                  "name",
                  "evalSpec"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created test case",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "The test case's unique id.",
                      "examples": [
                        "cmc3k5r2b0004l608w1t8fmz9"
                      ],
                      "type": "string"
                    },
                    "applicationId": {
                      "description": "Id of the application the test case is scoped to, or null for a company-wide test case.",
                      "examples": [
                        42
                      ],
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "agentId": {
                      "description": "Id of the agent the test case belongs to.",
                      "examples": [
                        "cmc3k1x9d0001l608r2vhq7e2"
                      ],
                      "type": "string"
                    },
                    "name": {
                      "description": "Human friendly name of the test case.",
                      "examples": [
                        "Order status happy path"
                      ],
                      "type": "string"
                    },
                    "description": {
                      "description": "Description of what the test case validates, or null.",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "scheduler": {
                      "description": "Cron expression for scheduled runs, or null when the test case only runs manually.",
                      "examples": [
                        "0 6 * * *"
                      ],
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "evalSpec": {
                      "description": "The full evaluation specification JSON document: ordered user messages and assertion steps, plus optional runtime context variables and webhook node mocks."
                    },
                    "enabled": {
                      "description": "Whether the test case can run, on schedule or manually.",
                      "examples": [
                        true
                      ],
                      "type": "boolean"
                    },
                    "lastRunAt": {
                      "description": "ISO 8601 timestamp of the last run, or null when the test case never ran.",
                      "examples": [
                        "2026-07-01T12:30:00.000Z"
                      ],
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "selfImproveEnabled": {
                      "description": "Whether self-improvement is enabled for this test case.",
                      "examples": [
                        false
                      ],
                      "type": "boolean"
                    },
                    "selfImproveTargetScore": {
                      "description": "Score from 0 to 10 that self-improvement tries to reach, or null.",
                      "examples": [
                        8
                      ],
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "selfImproveMaxIterations": {
                      "description": "Maximum number of self-improvement iterations.",
                      "examples": [
                        10
                      ],
                      "type": "number"
                    },
                    "folderId": {
                      "description": "Id of the folder the test case lives in, or null for the root level.",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "tags": {
                      "description": "Free-form labels of the test case.",
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "metadata": {
                      "description": "Free-form data about the test case, or null. `sources` holds its provenance: the threads, executions or messages it was built from.",
                      "anyOf": [
                        {
                          "description": "Free-form data recorded on the eval. Provenance belongs under `sources`, a list whose entries have documented keys so every writer points at the originating conversations the same way. An eval drawn from a single conversation carries a one-element list.",
                          "type": "object",
                          "properties": {
                            "sources": {
                              "description": "The conversations the eval was built from, most relevant first.",
                              "maxItems": 25,
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "threadId": {
                                    "description": "Id of the thread the eval was built from.",
                                    "examples": [
                                      "cmc3k5r2b0004l608w1t8fmz9"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 255
                                  },
                                  "executionId": {
                                    "description": "Id of the agent execution the eval was built from.",
                                    "examples": [
                                      "exec_01j9z3k2b4c5"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 255
                                  },
                                  "messageId": {
                                    "description": "Id of the specific message the eval was built from.",
                                    "examples": [
                                      "cmc3k9p7f0007"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 255
                                  },
                                  "url": {
                                    "description": "Link to the source conversation. Must be an absolute http(s) URL.",
                                    "examples": [
                                      "https://platform.docana.com/application/42/agents/a1/logs?search=thread-1"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 2048
                                  },
                                  "label": {
                                    "description": "Human friendly name of the source conversation.",
                                    "examples": [
                                      "WhatsApp 5511 — 12/08"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 255
                                  },
                                  "capturedAt": {
                                    "description": "ISO 8601 timestamp of when the eval was captured.",
                                    "examples": [
                                      "2026-08-17T12:00:00.000Z"
                                    ],
                                    "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))$"
                                  }
                                },
                                "additionalProperties": {}
                              }
                            }
                          },
                          "additionalProperties": {}
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "createdAt": {
                      "description": "ISO 8601 creation timestamp.",
                      "examples": [
                        "2026-06-15T09:00:00.000Z"
                      ],
                      "type": "string"
                    },
                    "updatedAt": {
                      "description": "ISO 8601 timestamp of the last update.",
                      "examples": [
                        "2026-07-01T12:30:00.000Z"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "applicationId",
                    "agentId",
                    "name",
                    "description",
                    "scheduler",
                    "evalSpec",
                    "enabled",
                    "lastRunAt",
                    "selfImproveEnabled",
                    "selfImproveTargetScore",
                    "selfImproveMaxIterations",
                    "createdAt",
                    "updatedAt"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "Invalid body",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Test case creation failure",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/test-cases/import/": {
      "post": {
        "operationId": "importAgentEvals",
        "summary": "Import evals from a bundle onto an existing agent",
        "tags": [
          "agent-testing"
        ],
        "description": "Imports the evals from an exported agent bundle onto an existing agent, leaving the agent itself untouched. Accepts the same file as `importAgents` — `application/json` or `multipart/form-data` with a `file` field — and reads its `agent.evals` plus the `agent.evalMockBaseline` those evals rely on. Evals are matched by name, so re-importing the same file updates the test cases rather than duplicating them. Nothing is executed: use `POST /api/v1/agents/{agentId}/test-cases/{testCaseId}/run/` to run one. Fails with 422 when an imported eval references an evaluation criterion the target agent does not have.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application to scope the request to. Omit to use the company-wide scope.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Import summary",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "agentId": {
                      "type": "string"
                    },
                    "importedCount": {
                      "description": "How many evals were written as test cases.",
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    }
                  },
                  "required": [
                    "ok",
                    "agentId",
                    "importedCount"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid payload or missing applicationId",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Agent not found in the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "422": {
            "description": "An imported eval references an unresolvable criterion",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "unresolvableCriteria": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ref": {
                            "description": "The criterion id as written in the imported eval.",
                            "type": "string"
                          },
                          "name": {
                            "description": "The bundle's name for that criterion, when the bundle defined it.",
                            "type": "string"
                          },
                          "ambiguous": {
                            "description": "Set when the target agent has more than one criterion with that name.",
                            "type": "boolean",
                            "const": true
                          }
                        },
                        "required": [
                          "ref"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "error",
                    "unresolvableCriteria"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/test-cases/{testCaseId}/": {
      "get": {
        "operationId": "getAgentTestCase",
        "summary": "Get a test case of an agent",
        "tags": [
          "agent-testing"
        ],
        "description": "Returns the full test case, including the `evalSpec` document with its user messages, assertions, context variables, and node mocks.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "testCaseId",
            "in": "path",
            "required": true,
            "description": "The test case's unique id.",
            "schema": {
              "examples": [
                "cmc3k5r2b0004l608w1t8fmz9"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application to scope the request to. Omit to use the company-wide scope.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The test case",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "The test case's unique id.",
                      "examples": [
                        "cmc3k5r2b0004l608w1t8fmz9"
                      ],
                      "type": "string"
                    },
                    "applicationId": {
                      "description": "Id of the application the test case is scoped to, or null for a company-wide test case.",
                      "examples": [
                        42
                      ],
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "agentId": {
                      "description": "Id of the agent the test case belongs to.",
                      "examples": [
                        "cmc3k1x9d0001l608r2vhq7e2"
                      ],
                      "type": "string"
                    },
                    "name": {
                      "description": "Human friendly name of the test case.",
                      "examples": [
                        "Order status happy path"
                      ],
                      "type": "string"
                    },
                    "description": {
                      "description": "Description of what the test case validates, or null.",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "scheduler": {
                      "description": "Cron expression for scheduled runs, or null when the test case only runs manually.",
                      "examples": [
                        "0 6 * * *"
                      ],
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "evalSpec": {
                      "description": "The full evaluation specification JSON document: ordered user messages and assertion steps, plus optional runtime context variables and webhook node mocks."
                    },
                    "enabled": {
                      "description": "Whether the test case can run, on schedule or manually.",
                      "examples": [
                        true
                      ],
                      "type": "boolean"
                    },
                    "lastRunAt": {
                      "description": "ISO 8601 timestamp of the last run, or null when the test case never ran.",
                      "examples": [
                        "2026-07-01T12:30:00.000Z"
                      ],
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "selfImproveEnabled": {
                      "description": "Whether self-improvement is enabled for this test case.",
                      "examples": [
                        false
                      ],
                      "type": "boolean"
                    },
                    "selfImproveTargetScore": {
                      "description": "Score from 0 to 10 that self-improvement tries to reach, or null.",
                      "examples": [
                        8
                      ],
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "selfImproveMaxIterations": {
                      "description": "Maximum number of self-improvement iterations.",
                      "examples": [
                        10
                      ],
                      "type": "number"
                    },
                    "folderId": {
                      "description": "Id of the folder the test case lives in, or null for the root level.",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "tags": {
                      "description": "Free-form labels of the test case.",
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "metadata": {
                      "description": "Free-form data about the test case, or null. `sources` holds its provenance: the threads, executions or messages it was built from.",
                      "anyOf": [
                        {
                          "description": "Free-form data recorded on the eval. Provenance belongs under `sources`, a list whose entries have documented keys so every writer points at the originating conversations the same way. An eval drawn from a single conversation carries a one-element list.",
                          "type": "object",
                          "properties": {
                            "sources": {
                              "description": "The conversations the eval was built from, most relevant first.",
                              "maxItems": 25,
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "threadId": {
                                    "description": "Id of the thread the eval was built from.",
                                    "examples": [
                                      "cmc3k5r2b0004l608w1t8fmz9"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 255
                                  },
                                  "executionId": {
                                    "description": "Id of the agent execution the eval was built from.",
                                    "examples": [
                                      "exec_01j9z3k2b4c5"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 255
                                  },
                                  "messageId": {
                                    "description": "Id of the specific message the eval was built from.",
                                    "examples": [
                                      "cmc3k9p7f0007"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 255
                                  },
                                  "url": {
                                    "description": "Link to the source conversation. Must be an absolute http(s) URL.",
                                    "examples": [
                                      "https://platform.docana.com/application/42/agents/a1/logs?search=thread-1"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 2048
                                  },
                                  "label": {
                                    "description": "Human friendly name of the source conversation.",
                                    "examples": [
                                      "WhatsApp 5511 — 12/08"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 255
                                  },
                                  "capturedAt": {
                                    "description": "ISO 8601 timestamp of when the eval was captured.",
                                    "examples": [
                                      "2026-08-17T12:00:00.000Z"
                                    ],
                                    "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))$"
                                  }
                                },
                                "additionalProperties": {}
                              }
                            }
                          },
                          "additionalProperties": {}
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "createdAt": {
                      "description": "ISO 8601 creation timestamp.",
                      "examples": [
                        "2026-06-15T09:00:00.000Z"
                      ],
                      "type": "string"
                    },
                    "updatedAt": {
                      "description": "ISO 8601 timestamp of the last update.",
                      "examples": [
                        "2026-07-01T12:30:00.000Z"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "applicationId",
                    "agentId",
                    "name",
                    "description",
                    "scheduler",
                    "evalSpec",
                    "enabled",
                    "lastRunAt",
                    "selfImproveEnabled",
                    "selfImproveTargetScore",
                    "selfImproveMaxIterations",
                    "createdAt",
                    "updatedAt"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Test case not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateAgentTestCase",
        "summary": "Update a test case of an agent",
        "tags": [
          "agent-testing"
        ],
        "description": "Applies a partial update: only the provided fields change. Pass `null` for `description` or `scheduler` to clear them. Returns the updated test case.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "testCaseId",
            "in": "path",
            "required": true,
            "description": "The test case's unique id.",
            "schema": {
              "examples": [
                "cmc3k5r2b0004l608w1t8fmz9"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "applicationId": {
                    "description": "Id of the application used to validate access. Omit to validate company-wide access.",
                    "examples": [
                      42
                    ],
                    "type": "number"
                  },
                  "name": {
                    "description": "New name of the test case. Must stay unique within the agent.",
                    "examples": [
                      "Order status happy path"
                    ],
                    "type": "string"
                  },
                  "description": {
                    "description": "New description of the test case. Pass null to clear it.",
                    "examples": [
                      "Checks that the agent reports the delivery status for an order number."
                    ],
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduler": {
                    "description": "New cron expression for scheduled runs. Pass null to remove the schedule.",
                    "examples": [
                      "0 6 * * *"
                    ],
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "enabled": {
                    "description": "Whether the test case can run, on schedule or manually.",
                    "examples": [
                      true
                    ],
                    "type": "boolean"
                  },
                  "evalSpec": {
                    "description": "Replacement evaluation specification: an ordered list of user messages and assertion steps, plus optional runtime context variables and webhook node mocks.",
                    "type": "object",
                    "properties": {
                      "context": {
                        "examples": [
                          {
                            "channel": "whatsapp",
                            "customerTier": "premium"
                          }
                        ],
                        "type": "object",
                        "propertyNames": {
                          "type": "string"
                        },
                        "additionalProperties": {
                          "$ref": "#/components/schemas/updateAgentTestCase_schema0"
                        }
                      },
                      "repeats": {
                        "examples": [
                          3
                        ],
                        "default": 1,
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 10
                      },
                      "minPassRate": {
                        "examples": [
                          0.67
                        ],
                        "default": 1,
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1
                      },
                      "advisory": {
                        "examples": [
                          false
                        ],
                        "default": false,
                        "type": "boolean"
                      },
                      "nodeMocks": {
                        "examples": [
                          {
                            "node_order_lookup": {
                              "type": "webhook",
                              "mode": "staticResponse",
                              "response": {
                                "status": 200,
                                "body": {
                                  "orderStatus": "shipped"
                                }
                              }
                            }
                          }
                        ],
                        "type": "object",
                        "propertyNames": {
                          "type": "string"
                        },
                        "additionalProperties": {
                          "anyOf": [
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "examples": [
                                    "webhook"
                                  ],
                                  "type": "string",
                                  "const": "webhook"
                                },
                                "mode": {
                                  "default": "staticResponse",
                                  "type": "string",
                                  "const": "staticResponse"
                                },
                                "response": {
                                  "anyOf": [
                                    {
                                      "type": "object",
                                      "properties": {
                                        "status": {
                                          "examples": [
                                            200
                                          ],
                                          "type": "integer",
                                          "minimum": 100,
                                          "maximum": 599
                                        },
                                        "headers": {
                                          "examples": [
                                            {
                                              "content-type": "application/json"
                                            }
                                          ],
                                          "type": "object",
                                          "propertyNames": {
                                            "type": "string"
                                          },
                                          "additionalProperties": {
                                            "type": "string"
                                          }
                                        },
                                        "body": {
                                          "examples": [
                                            {
                                              "orderStatus": "shipped"
                                            }
                                          ],
                                          "$ref": "#/components/schemas/updateAgentTestCase_schema0"
                                        },
                                        "noResponse": {
                                          "not": {}
                                        }
                                      },
                                      "required": [
                                        "status"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "noResponse": {
                                          "examples": [
                                            true
                                          ],
                                          "type": "boolean",
                                          "const": true
                                        },
                                        "error": {
                                          "examples": [
                                            "connect ECONNREFUSED 10.0.0.4:443"
                                          ],
                                          "type": "string"
                                        },
                                        "status": {
                                          "not": {}
                                        }
                                      },
                                      "required": [
                                        "noResponse"
                                      ]
                                    }
                                  ]
                                }
                              },
                              "required": [
                                "type",
                                "response"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "examples": [
                                    "webhook"
                                  ],
                                  "type": "string",
                                  "const": "webhook"
                                },
                                "mode": {
                                  "type": "string",
                                  "const": "sequence"
                                },
                                "responses": {
                                  "examples": [
                                    [
                                      {
                                        "status": 400,
                                        "body": {
                                          "error": "CEP inválido"
                                        }
                                      },
                                      {
                                        "status": 201,
                                        "body": {
                                          "data": {
                                            "status": "AUTORIZADA"
                                          }
                                        }
                                      }
                                    ]
                                  ],
                                  "minItems": 1,
                                  "type": "array",
                                  "items": {
                                    "anyOf": [
                                      {
                                        "type": "object",
                                        "properties": {
                                          "status": {
                                            "examples": [
                                              200
                                            ],
                                            "type": "integer",
                                            "minimum": 100,
                                            "maximum": 599
                                          },
                                          "headers": {
                                            "examples": [
                                              {
                                                "content-type": "application/json"
                                              }
                                            ],
                                            "type": "object",
                                            "propertyNames": {
                                              "type": "string"
                                            },
                                            "additionalProperties": {
                                              "type": "string"
                                            }
                                          },
                                          "body": {
                                            "examples": [
                                              {
                                                "orderStatus": "shipped"
                                              }
                                            ],
                                            "$ref": "#/components/schemas/updateAgentTestCase_schema0"
                                          },
                                          "noResponse": {
                                            "not": {}
                                          }
                                        },
                                        "required": [
                                          "status"
                                        ]
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "noResponse": {
                                            "examples": [
                                              true
                                            ],
                                            "type": "boolean",
                                            "const": true
                                          },
                                          "error": {
                                            "examples": [
                                              "connect ECONNREFUSED 10.0.0.4:443"
                                            ],
                                            "type": "string"
                                          },
                                          "status": {
                                            "not": {}
                                          }
                                        },
                                        "required": [
                                          "noResponse"
                                        ]
                                      }
                                    ]
                                  }
                                }
                              },
                              "required": [
                                "type",
                                "mode",
                                "responses"
                              ]
                            }
                          ]
                        }
                      },
                      "steps": {
                        "examples": [
                          [
                            {
                              "type": "user",
                              "text": "Where is my order #4821?"
                            },
                            {
                              "type": "smartAssertion",
                              "expectedOutput": "The agent confirms order 4821 shipped and gives the delivery date.",
                              "minScore": 7
                            }
                          ]
                        ],
                        "minItems": 1,
                        "type": "array",
                        "items": {
                          "oneOf": [
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "examples": [
                                    "user"
                                  ],
                                  "type": "string",
                                  "const": "user"
                                },
                                "text": {
                                  "examples": [
                                    "Where is my order #4821?"
                                  ],
                                  "type": "string",
                                  "minLength": 1
                                },
                                "attachments": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "url": {
                                        "examples": [
                                          "https://cdn.example.com/receipts/order-4821.pdf"
                                        ],
                                        "type": "string"
                                      },
                                      "name": {
                                        "examples": [
                                          "order-4821.pdf"
                                        ],
                                        "type": "string"
                                      },
                                      "contentType": {
                                        "examples": [
                                          "application/pdf"
                                        ],
                                        "type": "string"
                                      }
                                    },
                                    "required": [
                                      "url"
                                    ]
                                  }
                                },
                                "delayMs": {
                                  "examples": [
                                    1000
                                  ],
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 60000
                                },
                                "waitFor": {
                                  "examples": [
                                    "none"
                                  ],
                                  "type": "string",
                                  "enum": [
                                    "settled",
                                    "none"
                                  ]
                                },
                                "injectAfterNode": {
                                  "examples": [
                                    "n-n1jtll0d9"
                                  ],
                                  "type": "string",
                                  "minLength": 1
                                }
                              },
                              "required": [
                                "type",
                                "text"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "evaluationSteps": {
                                  "examples": [
                                    [
                                      "Check the reply names order 4821",
                                      "Check the reply states the delivery status"
                                    ]
                                  ],
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "expectedOutput": {
                                  "examples": [
                                    "The agent confirms order 4821 shipped and gives the delivery date."
                                  ],
                                  "type": "string"
                                },
                                "minScore": {
                                  "default": 7,
                                  "type": "number",
                                  "minimum": 0,
                                  "maximum": 10
                                },
                                "evaluationCriteria": {
                                  "examples": [
                                    "The reply must mention the order number and the current status."
                                  ],
                                  "type": "string"
                                },
                                "nodeId": {
                                  "examples": [
                                    "monta_report"
                                  ],
                                  "type": "string"
                                },
                                "selector": {
                                  "default": "last",
                                  "type": "string",
                                  "enum": [
                                    "first",
                                    "last"
                                  ]
                                },
                                "source": {
                                  "default": "output",
                                  "type": "string",
                                  "enum": [
                                    "input",
                                    "output",
                                    "record"
                                  ]
                                },
                                "path": {
                                  "examples": [
                                    "result.findings"
                                  ],
                                  "type": "string",
                                  "minLength": 1
                                },
                                "type": {
                                  "examples": [
                                    "smartAssertion"
                                  ],
                                  "type": "string",
                                  "const": "smartAssertion"
                                }
                              },
                              "required": [
                                "type"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "examples": [
                                    "actionAssertion"
                                  ],
                                  "type": "string",
                                  "const": "actionAssertion"
                                },
                                "actionType": {
                                  "type": "string",
                                  "enum": [
                                    "INSTRUCTIONS",
                                    "EMAIL",
                                    "WEBHOOK"
                                  ]
                                },
                                "operator": {
                                  "type": "string",
                                  "enum": [
                                    "eq",
                                    "gt",
                                    "lt"
                                  ]
                                },
                                "count": {
                                  "examples": [
                                    1
                                  ],
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 9007199254740991
                                },
                                "actionId": {
                                  "examples": [
                                    "action_refund_webhook"
                                  ],
                                  "type": "string"
                                },
                                "atLeast": {
                                  "examples": [
                                    1
                                  ],
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 9007199254740991
                                },
                                "equals": {
                                  "examples": [
                                    1
                                  ],
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 9007199254740991
                                }
                              },
                              "required": [
                                "type"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "examples": [
                                    "nodeAssertion"
                                  ],
                                  "type": "string",
                                  "const": "nodeAssertion"
                                },
                                "label": {
                                  "examples": [
                                    "Order lookup ran once"
                                  ],
                                  "type": "string"
                                },
                                "nodeId": {
                                  "examples": [
                                    "node_order_lookup"
                                  ],
                                  "type": "string"
                                },
                                "nodeType": {
                                  "examples": [
                                    "subAgent"
                                  ],
                                  "type": "string",
                                  "enum": [
                                    "action",
                                    "decision",
                                    "subAgent",
                                    "end",
                                    "state",
                                    "hub",
                                    "jump",
                                    "clearCache",
                                    "javascript",
                                    "forEach"
                                  ]
                                },
                                "operator": {
                                  "default": "gte",
                                  "type": "string",
                                  "enum": [
                                    "eq",
                                    "gt",
                                    "gte",
                                    "lt",
                                    "lte"
                                  ]
                                },
                                "count": {
                                  "default": 1,
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 9007199254740991
                                },
                                "selector": {
                                  "default": "any",
                                  "type": "string",
                                  "enum": [
                                    "first",
                                    "last",
                                    "any"
                                  ]
                                },
                                "assertions": {
                                  "default": [],
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "source": {
                                        "default": "output",
                                        "type": "string",
                                        "enum": [
                                          "input",
                                          "output",
                                          "record"
                                        ]
                                      },
                                      "path": {
                                        "examples": [
                                          "order.status"
                                        ],
                                        "type": "string",
                                        "minLength": 1
                                      },
                                      "operator": {
                                        "default": "exists",
                                        "type": "string",
                                        "enum": [
                                          "exists",
                                          "eq",
                                          "neq",
                                          "contains",
                                          "notContains",
                                          "gt",
                                          "gte",
                                          "lt",
                                          "lte"
                                        ]
                                      },
                                      "value": {
                                        "examples": [
                                          "shipped"
                                        ],
                                        "$ref": "#/components/schemas/updateAgentTestCase_schema0"
                                      },
                                      "label": {
                                        "examples": [
                                          "Order status is shipped"
                                        ],
                                        "type": "string"
                                      }
                                    },
                                    "required": [
                                      "path"
                                    ]
                                  }
                                }
                              },
                              "required": [
                                "type"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "examples": [
                                    "conversationAssertion"
                                  ],
                                  "type": "string",
                                  "const": "conversationAssertion"
                                },
                                "label": {
                                  "examples": [
                                    "Conversation never dies without a response"
                                  ],
                                  "type": "string"
                                },
                                "expectNoResponse": {
                                  "examples": [
                                    false
                                  ],
                                  "type": "boolean"
                                }
                              },
                              "required": [
                                "type",
                                "expectNoResponse"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "examples": [
                                    "assistant"
                                  ],
                                  "type": "string",
                                  "const": "assistant"
                                },
                                "text": {
                                  "examples": [
                                    "Seu pedido #123 saiu ontem e chega até sexta."
                                  ],
                                  "type": "string",
                                  "minLength": 1
                                }
                              },
                              "required": [
                                "type"
                              ]
                            }
                          ]
                        }
                      }
                    },
                    "required": [
                      "steps"
                    ]
                  },
                  "selfImproveEnabled": {
                    "description": "Whether self-improvement is enabled. When on, the platform runs the test, analyzes the scores, and iteratively refines the agent flow until the target score is reached.",
                    "examples": [
                      false
                    ],
                    "type": "boolean"
                  },
                  "selfImproveTargetScore": {
                    "description": "Score from 0 to 10 that self-improvement tries to reach.",
                    "examples": [
                      8
                    ],
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 10
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "selfImproveMaxIterations": {
                    "description": "Maximum number of self-improvement iterations, from 1 to 50.",
                    "examples": [
                      10
                    ],
                    "type": "number",
                    "minimum": 1,
                    "maximum": 50
                  },
                  "folderId": {
                    "description": "Id of the folder the test case lives in. Pass null to move it to the root level.",
                    "examples": [
                      "cmc3k7f1a0002l608q9d2xk41"
                    ],
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "tags": {
                    "description": "Replacement labels for the test case. Trimmed and deduplicated server-side.",
                    "examples": [
                      [
                        "smoke",
                        "checkout"
                      ]
                    ],
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "metadata": {
                    "description": "Replacement metadata document, including the `sources` provenance of the test case. Replaces the stored document wholesale rather than merging into it. Pass null to clear it; omit it to leave it untouched.",
                    "anyOf": [
                      {
                        "description": "Free-form data recorded on the eval. Provenance belongs under `sources`, a list whose entries have documented keys so every writer points at the originating conversations the same way. An eval drawn from a single conversation carries a one-element list.",
                        "type": "object",
                        "properties": {
                          "sources": {
                            "description": "The conversations the eval was built from, most relevant first.",
                            "maxItems": 25,
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "threadId": {
                                  "description": "Id of the thread the eval was built from.",
                                  "examples": [
                                    "cmc3k5r2b0004l608w1t8fmz9"
                                  ],
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 255
                                },
                                "executionId": {
                                  "description": "Id of the agent execution the eval was built from.",
                                  "examples": [
                                    "exec_01j9z3k2b4c5"
                                  ],
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 255
                                },
                                "messageId": {
                                  "description": "Id of the specific message the eval was built from.",
                                  "examples": [
                                    "cmc3k9p7f0007"
                                  ],
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 255
                                },
                                "url": {
                                  "description": "Link to the source conversation. Must be an absolute http(s) URL.",
                                  "examples": [
                                    "https://platform.docana.com/application/42/agents/a1/logs?search=thread-1"
                                  ],
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 2048
                                },
                                "label": {
                                  "description": "Human friendly name of the source conversation.",
                                  "examples": [
                                    "WhatsApp 5511 — 12/08"
                                  ],
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 255
                                },
                                "capturedAt": {
                                  "description": "ISO 8601 timestamp of when the eval was captured.",
                                  "examples": [
                                    "2026-08-17T12:00:00.000Z"
                                  ],
                                  "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))$"
                                }
                              },
                              "additionalProperties": {}
                            }
                          }
                        },
                        "additionalProperties": {}
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated test case",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "The test case's unique id.",
                      "examples": [
                        "cmc3k5r2b0004l608w1t8fmz9"
                      ],
                      "type": "string"
                    },
                    "applicationId": {
                      "description": "Id of the application the test case is scoped to, or null for a company-wide test case.",
                      "examples": [
                        42
                      ],
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "agentId": {
                      "description": "Id of the agent the test case belongs to.",
                      "examples": [
                        "cmc3k1x9d0001l608r2vhq7e2"
                      ],
                      "type": "string"
                    },
                    "name": {
                      "description": "Human friendly name of the test case.",
                      "examples": [
                        "Order status happy path"
                      ],
                      "type": "string"
                    },
                    "description": {
                      "description": "Description of what the test case validates, or null.",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "scheduler": {
                      "description": "Cron expression for scheduled runs, or null when the test case only runs manually.",
                      "examples": [
                        "0 6 * * *"
                      ],
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "evalSpec": {
                      "description": "The full evaluation specification JSON document: ordered user messages and assertion steps, plus optional runtime context variables and webhook node mocks."
                    },
                    "enabled": {
                      "description": "Whether the test case can run, on schedule or manually.",
                      "examples": [
                        true
                      ],
                      "type": "boolean"
                    },
                    "lastRunAt": {
                      "description": "ISO 8601 timestamp of the last run, or null when the test case never ran.",
                      "examples": [
                        "2026-07-01T12:30:00.000Z"
                      ],
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "selfImproveEnabled": {
                      "description": "Whether self-improvement is enabled for this test case.",
                      "examples": [
                        false
                      ],
                      "type": "boolean"
                    },
                    "selfImproveTargetScore": {
                      "description": "Score from 0 to 10 that self-improvement tries to reach, or null.",
                      "examples": [
                        8
                      ],
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "selfImproveMaxIterations": {
                      "description": "Maximum number of self-improvement iterations.",
                      "examples": [
                        10
                      ],
                      "type": "number"
                    },
                    "folderId": {
                      "description": "Id of the folder the test case lives in, or null for the root level.",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "tags": {
                      "description": "Free-form labels of the test case.",
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "metadata": {
                      "description": "Free-form data about the test case, or null. `sources` holds its provenance: the threads, executions or messages it was built from.",
                      "anyOf": [
                        {
                          "description": "Free-form data recorded on the eval. Provenance belongs under `sources`, a list whose entries have documented keys so every writer points at the originating conversations the same way. An eval drawn from a single conversation carries a one-element list.",
                          "type": "object",
                          "properties": {
                            "sources": {
                              "description": "The conversations the eval was built from, most relevant first.",
                              "maxItems": 25,
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "threadId": {
                                    "description": "Id of the thread the eval was built from.",
                                    "examples": [
                                      "cmc3k5r2b0004l608w1t8fmz9"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 255
                                  },
                                  "executionId": {
                                    "description": "Id of the agent execution the eval was built from.",
                                    "examples": [
                                      "exec_01j9z3k2b4c5"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 255
                                  },
                                  "messageId": {
                                    "description": "Id of the specific message the eval was built from.",
                                    "examples": [
                                      "cmc3k9p7f0007"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 255
                                  },
                                  "url": {
                                    "description": "Link to the source conversation. Must be an absolute http(s) URL.",
                                    "examples": [
                                      "https://platform.docana.com/application/42/agents/a1/logs?search=thread-1"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 2048
                                  },
                                  "label": {
                                    "description": "Human friendly name of the source conversation.",
                                    "examples": [
                                      "WhatsApp 5511 — 12/08"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 255
                                  },
                                  "capturedAt": {
                                    "description": "ISO 8601 timestamp of when the eval was captured.",
                                    "examples": [
                                      "2026-08-17T12:00:00.000Z"
                                    ],
                                    "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))$"
                                  }
                                },
                                "additionalProperties": {}
                              }
                            }
                          },
                          "additionalProperties": {}
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "createdAt": {
                      "description": "ISO 8601 creation timestamp.",
                      "examples": [
                        "2026-06-15T09:00:00.000Z"
                      ],
                      "type": "string"
                    },
                    "updatedAt": {
                      "description": "ISO 8601 timestamp of the last update.",
                      "examples": [
                        "2026-07-01T12:30:00.000Z"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "applicationId",
                    "agentId",
                    "name",
                    "description",
                    "scheduler",
                    "evalSpec",
                    "enabled",
                    "lastRunAt",
                    "selfImproveEnabled",
                    "selfImproveTargetScore",
                    "selfImproveMaxIterations",
                    "createdAt",
                    "updatedAt"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "Invalid body",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Test case not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteAgentTestCase",
        "summary": "Delete a test case of an agent",
        "tags": [
          "agent-testing"
        ],
        "description": "Permanently deletes the test case together with its test runs, which cascade with it. Returns the deleted test case.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "testCaseId",
            "in": "path",
            "required": true,
            "description": "The test case's unique id.",
            "schema": {
              "examples": [
                "cmc3k5r2b0004l608w1t8fmz9"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application to scope the request to. Omit to use the company-wide scope.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The deleted test case",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "The test case's unique id.",
                      "examples": [
                        "cmc3k5r2b0004l608w1t8fmz9"
                      ],
                      "type": "string"
                    },
                    "applicationId": {
                      "description": "Id of the application the test case is scoped to, or null for a company-wide test case.",
                      "examples": [
                        42
                      ],
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "agentId": {
                      "description": "Id of the agent the test case belongs to.",
                      "examples": [
                        "cmc3k1x9d0001l608r2vhq7e2"
                      ],
                      "type": "string"
                    },
                    "name": {
                      "description": "Human friendly name of the test case.",
                      "examples": [
                        "Order status happy path"
                      ],
                      "type": "string"
                    },
                    "description": {
                      "description": "Description of what the test case validates, or null.",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "scheduler": {
                      "description": "Cron expression for scheduled runs, or null when the test case only runs manually.",
                      "examples": [
                        "0 6 * * *"
                      ],
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "evalSpec": {
                      "description": "The full evaluation specification JSON document: ordered user messages and assertion steps, plus optional runtime context variables and webhook node mocks."
                    },
                    "enabled": {
                      "description": "Whether the test case can run, on schedule or manually.",
                      "examples": [
                        true
                      ],
                      "type": "boolean"
                    },
                    "lastRunAt": {
                      "description": "ISO 8601 timestamp of the last run, or null when the test case never ran.",
                      "examples": [
                        "2026-07-01T12:30:00.000Z"
                      ],
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "selfImproveEnabled": {
                      "description": "Whether self-improvement is enabled for this test case.",
                      "examples": [
                        false
                      ],
                      "type": "boolean"
                    },
                    "selfImproveTargetScore": {
                      "description": "Score from 0 to 10 that self-improvement tries to reach, or null.",
                      "examples": [
                        8
                      ],
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "selfImproveMaxIterations": {
                      "description": "Maximum number of self-improvement iterations.",
                      "examples": [
                        10
                      ],
                      "type": "number"
                    },
                    "folderId": {
                      "description": "Id of the folder the test case lives in, or null for the root level.",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "tags": {
                      "description": "Free-form labels of the test case.",
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "metadata": {
                      "description": "Free-form data about the test case, or null. `sources` holds its provenance: the threads, executions or messages it was built from.",
                      "anyOf": [
                        {
                          "description": "Free-form data recorded on the eval. Provenance belongs under `sources`, a list whose entries have documented keys so every writer points at the originating conversations the same way. An eval drawn from a single conversation carries a one-element list.",
                          "type": "object",
                          "properties": {
                            "sources": {
                              "description": "The conversations the eval was built from, most relevant first.",
                              "maxItems": 25,
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "threadId": {
                                    "description": "Id of the thread the eval was built from.",
                                    "examples": [
                                      "cmc3k5r2b0004l608w1t8fmz9"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 255
                                  },
                                  "executionId": {
                                    "description": "Id of the agent execution the eval was built from.",
                                    "examples": [
                                      "exec_01j9z3k2b4c5"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 255
                                  },
                                  "messageId": {
                                    "description": "Id of the specific message the eval was built from.",
                                    "examples": [
                                      "cmc3k9p7f0007"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 255
                                  },
                                  "url": {
                                    "description": "Link to the source conversation. Must be an absolute http(s) URL.",
                                    "examples": [
                                      "https://platform.docana.com/application/42/agents/a1/logs?search=thread-1"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 2048
                                  },
                                  "label": {
                                    "description": "Human friendly name of the source conversation.",
                                    "examples": [
                                      "WhatsApp 5511 — 12/08"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 255
                                  },
                                  "capturedAt": {
                                    "description": "ISO 8601 timestamp of when the eval was captured.",
                                    "examples": [
                                      "2026-08-17T12:00:00.000Z"
                                    ],
                                    "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))$"
                                  }
                                },
                                "additionalProperties": {}
                              }
                            }
                          },
                          "additionalProperties": {}
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "createdAt": {
                      "description": "ISO 8601 creation timestamp.",
                      "examples": [
                        "2026-06-15T09:00:00.000Z"
                      ],
                      "type": "string"
                    },
                    "updatedAt": {
                      "description": "ISO 8601 timestamp of the last update.",
                      "examples": [
                        "2026-07-01T12:30:00.000Z"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "applicationId",
                    "agentId",
                    "name",
                    "description",
                    "scheduler",
                    "evalSpec",
                    "enabled",
                    "lastRunAt",
                    "selfImproveEnabled",
                    "selfImproveTargetScore",
                    "selfImproveMaxIterations",
                    "createdAt",
                    "updatedAt"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Test case not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/test-cases/{testCaseId}/duplicate/": {
      "post": {
        "operationId": "duplicateAgentTestCase",
        "summary": "Duplicate a test case of an agent",
        "tags": [
          "agent-testing"
        ],
        "description": "Copies the eval spec, description, scheduler, and self-improvement settings into a new test case. When `name` is omitted, a unique name is derived from the source name plus `duplicateNameSuffix`, for example `Order status (Copy)` or `Order status (Copy 2)`. The application scope comes from `applicationId` in the body, or from the query string when the body omits it.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "testCaseId",
            "in": "path",
            "required": true,
            "description": "The test case's unique id.",
            "schema": {
              "examples": [
                "cmc3k5r2b0004l608w1t8fmz9"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application to scope the request to. Omit to use the company-wide scope.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "applicationId": {
                    "description": "Id of the application used to validate access and scope the lookup. Omit to validate company-wide access.",
                    "examples": [
                      42
                    ],
                    "type": "number"
                  },
                  "name": {
                    "description": "Explicit name for the duplicate. When omitted, a unique name is derived from the source name and the suffix.",
                    "examples": [
                      "Order status happy path v2"
                    ],
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "duplicateNameSuffix": {
                    "description": "Suffix appended in parentheses when deriving the duplicate name, producing names like \"Order status (Copy)\" and \"Order status (Copy 2)\". Defaults to \"Copy\".",
                    "examples": [
                      "Copy"
                    ],
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 50
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The duplicated test case",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "The test case's unique id.",
                      "examples": [
                        "cmc3k5r2b0004l608w1t8fmz9"
                      ],
                      "type": "string"
                    },
                    "applicationId": {
                      "description": "Id of the application the test case is scoped to, or null for a company-wide test case.",
                      "examples": [
                        42
                      ],
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "agentId": {
                      "description": "Id of the agent the test case belongs to.",
                      "examples": [
                        "cmc3k1x9d0001l608r2vhq7e2"
                      ],
                      "type": "string"
                    },
                    "name": {
                      "description": "Human friendly name of the test case.",
                      "examples": [
                        "Order status happy path"
                      ],
                      "type": "string"
                    },
                    "description": {
                      "description": "Description of what the test case validates, or null.",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "scheduler": {
                      "description": "Cron expression for scheduled runs, or null when the test case only runs manually.",
                      "examples": [
                        "0 6 * * *"
                      ],
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "evalSpec": {
                      "description": "The full evaluation specification JSON document: ordered user messages and assertion steps, plus optional runtime context variables and webhook node mocks."
                    },
                    "enabled": {
                      "description": "Whether the test case can run, on schedule or manually.",
                      "examples": [
                        true
                      ],
                      "type": "boolean"
                    },
                    "lastRunAt": {
                      "description": "ISO 8601 timestamp of the last run, or null when the test case never ran.",
                      "examples": [
                        "2026-07-01T12:30:00.000Z"
                      ],
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "selfImproveEnabled": {
                      "description": "Whether self-improvement is enabled for this test case.",
                      "examples": [
                        false
                      ],
                      "type": "boolean"
                    },
                    "selfImproveTargetScore": {
                      "description": "Score from 0 to 10 that self-improvement tries to reach, or null.",
                      "examples": [
                        8
                      ],
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "selfImproveMaxIterations": {
                      "description": "Maximum number of self-improvement iterations.",
                      "examples": [
                        10
                      ],
                      "type": "number"
                    },
                    "folderId": {
                      "description": "Id of the folder the test case lives in, or null for the root level.",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "tags": {
                      "description": "Free-form labels of the test case.",
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "metadata": {
                      "description": "Free-form data about the test case, or null. `sources` holds its provenance: the threads, executions or messages it was built from.",
                      "anyOf": [
                        {
                          "description": "Free-form data recorded on the eval. Provenance belongs under `sources`, a list whose entries have documented keys so every writer points at the originating conversations the same way. An eval drawn from a single conversation carries a one-element list.",
                          "type": "object",
                          "properties": {
                            "sources": {
                              "description": "The conversations the eval was built from, most relevant first.",
                              "maxItems": 25,
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "threadId": {
                                    "description": "Id of the thread the eval was built from.",
                                    "examples": [
                                      "cmc3k5r2b0004l608w1t8fmz9"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 255
                                  },
                                  "executionId": {
                                    "description": "Id of the agent execution the eval was built from.",
                                    "examples": [
                                      "exec_01j9z3k2b4c5"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 255
                                  },
                                  "messageId": {
                                    "description": "Id of the specific message the eval was built from.",
                                    "examples": [
                                      "cmc3k9p7f0007"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 255
                                  },
                                  "url": {
                                    "description": "Link to the source conversation. Must be an absolute http(s) URL.",
                                    "examples": [
                                      "https://platform.docana.com/application/42/agents/a1/logs?search=thread-1"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 2048
                                  },
                                  "label": {
                                    "description": "Human friendly name of the source conversation.",
                                    "examples": [
                                      "WhatsApp 5511 — 12/08"
                                    ],
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 255
                                  },
                                  "capturedAt": {
                                    "description": "ISO 8601 timestamp of when the eval was captured.",
                                    "examples": [
                                      "2026-08-17T12:00:00.000Z"
                                    ],
                                    "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))$"
                                  }
                                },
                                "additionalProperties": {}
                              }
                            }
                          },
                          "additionalProperties": {}
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "createdAt": {
                      "description": "ISO 8601 creation timestamp.",
                      "examples": [
                        "2026-06-15T09:00:00.000Z"
                      ],
                      "type": "string"
                    },
                    "updatedAt": {
                      "description": "ISO 8601 timestamp of the last update.",
                      "examples": [
                        "2026-07-01T12:30:00.000Z"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "applicationId",
                    "agentId",
                    "name",
                    "description",
                    "scheduler",
                    "evalSpec",
                    "enabled",
                    "lastRunAt",
                    "selfImproveEnabled",
                    "selfImproveTargetScore",
                    "selfImproveMaxIterations",
                    "createdAt",
                    "updatedAt"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "Invalid body",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Test case not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/test-cases/{testCaseId}/run/": {
      "post": {
        "operationId": "runAgentTestCase",
        "summary": "Run a test case of an agent",
        "tags": [
          "agent-testing"
        ],
        "description": "Queues the evaluation and returns immediately with a stable `runId`. The queued run is visible immediately; the worker atomically claims it before evaluation. The evaluation replays the eval spec steps against the agent and records per-step results. Poll `GET /api/v1/agents/{agentId}/test-runs/{runId}/` to track progress and use `POST /api/v1/agents/{agentId}/test-runs/{runId}/stop/` to cancel. The test case must be enabled and associated with an application. Accepts an optional JSON body `{ repeats?, minPassRate? }` to override the eval spec's own values for this run only.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "testCaseId",
            "in": "path",
            "required": true,
            "description": "The test case's unique id.",
            "schema": {
              "examples": [
                "cmc3k5r2b0004l608w1t8fmz9"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Optional per-run overrides for `repeats` (1-10) and `minPassRate` (0-1). Omit to use the spec defaults.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "repeats": {
                    "description": "Overrides the spec-level `repeats` for this run only.",
                    "examples": [
                      3
                    ],
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 10
                  },
                  "minPassRate": {
                    "description": "Overrides the spec-level `minPassRate` for this run only.",
                    "examples": [
                      0.8
                    ],
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The test run was scheduled",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the test run was scheduled.",
                      "examples": [
                        true
                      ],
                      "type": "boolean"
                    },
                    "runId": {
                      "description": "Id of the created test run. Poll `GET /api/v1/agents/{agentId}/test-runs/{runId}/` with it to track progress.",
                      "examples": [
                        "cmc3k9p7f0007l608u3jdx4a1"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "success",
                    "runId"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Test case not runnable (wrong agent, disabled, no application) or invalid body",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Test case not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Failed to schedule the test run",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/test-cases/generate-spec/": {
      "post": {
        "operationId": "generateAgentTestCaseSpec",
        "summary": "Generate a test case spec from the agent flow",
        "tags": [
          "agent-testing"
        ],
        "description": "Accepts an optional JSON body `{ currentTestCase?: { name?, description?, evalSpec? }, additionalInstructions? }` used to seed and steer the LLM generation.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application to scope the request to. Omit to use the company-wide scope.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Optional seed data and instructions. A missing body generates from the agent flow alone.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "currentTestCase": {
                    "description": "The test case being edited, used to seed the generation.",
                    "type": "object",
                    "properties": {
                      "name": {
                        "description": "Name of the test case currently in the editor.",
                        "examples": [
                          "Order status happy path"
                        ],
                        "type": "string"
                      },
                      "description": {
                        "description": "Description of the test case currently in the editor.",
                        "examples": [
                          "Checks that the agent reports the delivery status for an order number."
                        ],
                        "type": "string"
                      },
                      "evalSpec": {
                        "description": "Eval spec of the test case currently in the editor.",
                        "examples": [
                          {
                            "steps": [
                              {
                                "type": "user",
                                "text": "Where is my order #4821?"
                              }
                            ]
                          }
                        ]
                      }
                    }
                  },
                  "additionalInstructions": {
                    "description": "Free-text requirements the generated test case must incorporate. Empty strings are ignored.",
                    "examples": [
                      "Cover the refund flow and assert the refund webhook fires exactly once."
                    ],
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The generated test case spec",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when generation succeeded.",
                      "examples": [
                        true
                      ],
                      "type": "boolean"
                    },
                    "name": {
                      "description": "Generated name for the test case.",
                      "examples": [
                        "Order status happy path"
                      ],
                      "type": "string"
                    },
                    "description": {
                      "description": "Generated description of what the test case validates.",
                      "type": "string"
                    },
                    "evalSpec": {
                      "description": "Generated evaluation specification, already validated against the eval spec schema."
                    }
                  },
                  "required": [
                    "success",
                    "name",
                    "description",
                    "evalSpec"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid workflow or generated spec failed validation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions on the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Generation failure",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/test-cases/update-from-flow/": {
      "post": {
        "operationId": "updateAgentTestCasesFromFlow",
        "summary": "Generate or update test cases from the agent flow",
        "tags": [
          "agent-testing"
        ],
        "description": "Reads the agent's live workflow and derives one skeleton test case per decision and action node, without using an LLM (see `POST /api/v1/agents/{agentId}/test-cases/generate-spec/` for LLM generation). Existing test cases are matched by name: matches are updated in place and the rest are created. The response lists each affected test case with the action taken.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application to scope the request to. Omit to use the company-wide scope.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The generated and updated test cases",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the generation completed.",
                      "examples": [
                        true
                      ],
                      "type": "boolean"
                    },
                    "message": {
                      "description": "Human readable summary of the outcome.",
                      "examples": [
                        "Generated 4 test cases from agent flow."
                      ],
                      "type": "string"
                    },
                    "results": {
                      "description": "One entry per test case that was created or updated from the flow.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "action": {
                            "description": "Whether the test case was newly created or an existing one was updated.",
                            "examples": [
                              "created"
                            ],
                            "type": "string",
                            "enum": [
                              "created",
                              "updated"
                            ]
                          },
                          "id": {
                            "description": "The test case's unique id.",
                            "examples": [
                              "cmc3k5r2b0004l608w1t8fmz9"
                            ],
                            "type": "string"
                          },
                          "name": {
                            "description": "Name of the test case.",
                            "examples": [
                              "Test: Order lookup"
                            ],
                            "type": "string"
                          }
                        },
                        "required": [
                          "action",
                          "id",
                          "name"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "results"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Agent spec does not contain a valid workflow",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions on the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Update failure",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/test-case-folders/": {
      "get": {
        "operationId": "listAgentTestCaseFolders",
        "summary": "List the test-case folders of an agent",
        "tags": [
          "agent-testing"
        ],
        "description": "Returns every test-case folder of the agent as a flat list; build the tree client-side from `parentId`. Folders organize the evals shown by the platform UI. Assign a test case to a folder with the `folderId` field on the test-case endpoints.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application to scope the request to. Omit to use the company-wide scope.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The folders of the agent",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "description": "The folder's unique id.",
                        "examples": [
                          "cmc3k7f1a0002l608q9d2xk41"
                        ],
                        "type": "string"
                      },
                      "agentId": {
                        "description": "Id of the agent the folder belongs to.",
                        "examples": [
                          "cmc3k1x9d0001l608r2vhq7e2"
                        ],
                        "type": "string"
                      },
                      "applicationId": {
                        "description": "Id of the application the folder is scoped to, or null.",
                        "examples": [
                          42
                        ],
                        "anyOf": [
                          {
                            "type": "number"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "name": {
                        "description": "Name of the folder.",
                        "examples": [
                          "Regressão"
                        ],
                        "type": "string"
                      },
                      "parentId": {
                        "description": "Id of the parent folder, or null for a root folder.",
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "createdAt": {
                        "description": "ISO 8601 creation timestamp.",
                        "examples": [
                          "2026-08-15T09:00:00.000Z"
                        ],
                        "type": "string"
                      },
                      "updatedAt": {
                        "description": "ISO 8601 timestamp of the last update.",
                        "examples": [
                          "2026-08-15T09:00:00.000Z"
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "id",
                      "agentId",
                      "applicationId",
                      "name",
                      "parentId",
                      "createdAt",
                      "updatedAt"
                    ],
                    "additionalProperties": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createAgentTestCaseFolder",
        "summary": "Create a test-case folder for an agent",
        "tags": [
          "agent-testing"
        ],
        "description": "Creates a folder for organizing the agent's test cases. Folder names must be unique among siblings and must not contain '/'. Pass `parentId` to create a subfolder. The application scope comes from `applicationId` in the body, or from the query string when the body omits it — matching the other test-case endpoints.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application to scope the request to. Omit to use the company-wide scope.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "applicationId": {
                    "description": "Id of the application the folder is scoped to. Omit to use the company-wide scope.",
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  "name": {
                    "description": "Name of the folder. Must not contain '/'.",
                    "examples": [
                      "Regressão"
                    ],
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "parentId": {
                    "description": "Id of the parent folder, or null/omitted for a root folder.",
                    "examples": [
                      null
                    ],
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created folder",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "The folder's unique id.",
                      "examples": [
                        "cmc3k7f1a0002l608q9d2xk41"
                      ],
                      "type": "string"
                    },
                    "agentId": {
                      "description": "Id of the agent the folder belongs to.",
                      "examples": [
                        "cmc3k1x9d0001l608r2vhq7e2"
                      ],
                      "type": "string"
                    },
                    "applicationId": {
                      "description": "Id of the application the folder is scoped to, or null.",
                      "examples": [
                        42
                      ],
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "name": {
                      "description": "Name of the folder.",
                      "examples": [
                        "Regressão"
                      ],
                      "type": "string"
                    },
                    "parentId": {
                      "description": "Id of the parent folder, or null for a root folder.",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "createdAt": {
                      "description": "ISO 8601 creation timestamp.",
                      "examples": [
                        "2026-08-15T09:00:00.000Z"
                      ],
                      "type": "string"
                    },
                    "updatedAt": {
                      "description": "ISO 8601 timestamp of the last update.",
                      "examples": [
                        "2026-08-15T09:00:00.000Z"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "agentId",
                    "applicationId",
                    "name",
                    "parentId",
                    "createdAt",
                    "updatedAt"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or parent folder",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "A sibling folder with the same name already exists",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/test-case-folders/{folderId}/": {
      "patch": {
        "operationId": "updateAgentTestCaseFolder",
        "summary": "Update a test-case folder of an agent",
        "tags": [
          "agent-testing"
        ],
        "description": "Applies a partial update: only the provided fields change. Pass `parentId: null` to move the folder to the root. Moving a folder inside itself or one of its subfolders is rejected, as are sibling-name conflicts at the destination. The application scope comes from `applicationId` in the body, or from the query string when the body omits it.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "folderId",
            "in": "path",
            "required": true,
            "description": "The folder's unique id.",
            "schema": {
              "examples": [
                "cmc3k7f1a0002l608q9d2xk41"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application to scope the request to. Omit to use the company-wide scope.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "applicationId": {
                    "description": "Id of the application used to validate access. Omit to validate company-wide access.",
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  "name": {
                    "description": "Name of the folder. Must not contain '/'.",
                    "examples": [
                      "Regressão"
                    ],
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "parentId": {
                    "description": "New parent folder id, or null to move the folder to the root. Moving a folder inside itself or one of its subfolders is rejected.",
                    "examples": [
                      null
                    ],
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated folder",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "The folder's unique id.",
                      "examples": [
                        "cmc3k7f1a0002l608q9d2xk41"
                      ],
                      "type": "string"
                    },
                    "agentId": {
                      "description": "Id of the agent the folder belongs to.",
                      "examples": [
                        "cmc3k1x9d0001l608r2vhq7e2"
                      ],
                      "type": "string"
                    },
                    "applicationId": {
                      "description": "Id of the application the folder is scoped to, or null.",
                      "examples": [
                        42
                      ],
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "name": {
                      "description": "Name of the folder.",
                      "examples": [
                        "Regressão"
                      ],
                      "type": "string"
                    },
                    "parentId": {
                      "description": "Id of the parent folder, or null for a root folder.",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "createdAt": {
                      "description": "ISO 8601 creation timestamp.",
                      "examples": [
                        "2026-08-15T09:00:00.000Z"
                      ],
                      "type": "string"
                    },
                    "updatedAt": {
                      "description": "ISO 8601 timestamp of the last update.",
                      "examples": [
                        "2026-08-15T09:00:00.000Z"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "agentId",
                    "applicationId",
                    "name",
                    "parentId",
                    "createdAt",
                    "updatedAt"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "Invalid body, parent folder, or move",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Folder not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "409": {
            "description": "A sibling folder with the same name already exists",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteAgentTestCaseFolder",
        "summary": "Delete a test-case folder of an agent",
        "tags": [
          "agent-testing"
        ],
        "description": "Deletes the folder. Its subfolders and test cases are moved to the deleted folder's parent (or to the root), never deleted.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "folderId",
            "in": "path",
            "required": true,
            "description": "The folder's unique id.",
            "schema": {
              "examples": [
                "cmc3k7f1a0002l608q9d2xk41"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application to scope the request to. Omit to use the company-wide scope.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The deleted folder",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "The folder's unique id.",
                      "examples": [
                        "cmc3k7f1a0002l608q9d2xk41"
                      ],
                      "type": "string"
                    },
                    "agentId": {
                      "description": "Id of the agent the folder belongs to.",
                      "examples": [
                        "cmc3k1x9d0001l608r2vhq7e2"
                      ],
                      "type": "string"
                    },
                    "applicationId": {
                      "description": "Id of the application the folder is scoped to, or null.",
                      "examples": [
                        42
                      ],
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "name": {
                      "description": "Name of the folder.",
                      "examples": [
                        "Regressão"
                      ],
                      "type": "string"
                    },
                    "parentId": {
                      "description": "Id of the parent folder, or null for a root folder.",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "createdAt": {
                      "description": "ISO 8601 creation timestamp.",
                      "examples": [
                        "2026-08-15T09:00:00.000Z"
                      ],
                      "type": "string"
                    },
                    "updatedAt": {
                      "description": "ISO 8601 timestamp of the last update.",
                      "examples": [
                        "2026-08-15T09:00:00.000Z"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "agentId",
                    "applicationId",
                    "name",
                    "parentId",
                    "createdAt",
                    "updatedAt"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Folder not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/eval-mock-baseline/": {
      "get": {
        "operationId": "getAgentEvalMockBaseline",
        "summary": "Get the baseline node mocks of an agent",
        "tags": [
          "agent-testing"
        ],
        "description": "Baseline node mocks are the fallback underneath every eval of this agent. When an eval runs, its own `nodeMocks` win per node id and the baseline answers for the rest. An agent without a baseline behaves exactly as it did before baselines existed: a node with no mock performs a real webhook call. Returns 404 when the agent has no baseline.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application to scope the request to. Omit to use the company-wide scope.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The agent's baseline node mocks",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "The baseline's unique id.",
                      "examples": [
                        "cmc3k7f1a0002l608q9d2xk41"
                      ],
                      "type": "string"
                    },
                    "agentId": {
                      "description": "Id of the agent the baseline belongs to.",
                      "examples": [
                        "cmc3k1x9d0001l608r2vhq7e2"
                      ],
                      "type": "string"
                    },
                    "applicationId": {
                      "description": "Id of the application the baseline is scoped to, or null.",
                      "examples": [
                        42
                      ],
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "mocks": {
                      "description": "Node mocks every eval of this agent inherits, keyed by node id. Same shape as an eval spec’s `nodeMocks`.",
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {
                        "anyOf": [
                          {
                            "type": "object",
                            "properties": {
                              "type": {
                                "examples": [
                                  "webhook"
                                ],
                                "type": "string",
                                "const": "webhook"
                              },
                              "mode": {
                                "default": "staticResponse",
                                "type": "string",
                                "const": "staticResponse"
                              },
                              "response": {
                                "anyOf": [
                                  {
                                    "type": "object",
                                    "properties": {
                                      "status": {
                                        "examples": [
                                          200
                                        ],
                                        "type": "integer",
                                        "minimum": 100,
                                        "maximum": 599
                                      },
                                      "headers": {
                                        "examples": [
                                          {
                                            "content-type": "application/json"
                                          }
                                        ],
                                        "type": "object",
                                        "propertyNames": {
                                          "type": "string"
                                        },
                                        "additionalProperties": {
                                          "type": "string"
                                        }
                                      },
                                      "body": {
                                        "examples": [
                                          {
                                            "orderStatus": "shipped"
                                          }
                                        ],
                                        "$ref": "#/components/schemas/getAgentEvalMockBaseline_schema0"
                                      },
                                      "noResponse": {
                                        "not": {}
                                      }
                                    },
                                    "required": [
                                      "status"
                                    ],
                                    "additionalProperties": false
                                  },
                                  {
                                    "type": "object",
                                    "properties": {
                                      "noResponse": {
                                        "examples": [
                                          true
                                        ],
                                        "type": "boolean",
                                        "const": true
                                      },
                                      "error": {
                                        "examples": [
                                          "connect ECONNREFUSED 10.0.0.4:443"
                                        ],
                                        "type": "string"
                                      },
                                      "status": {
                                        "not": {}
                                      }
                                    },
                                    "required": [
                                      "noResponse"
                                    ],
                                    "additionalProperties": false
                                  }
                                ]
                              }
                            },
                            "required": [
                              "type",
                              "mode",
                              "response"
                            ],
                            "additionalProperties": false
                          },
                          {
                            "type": "object",
                            "properties": {
                              "type": {
                                "examples": [
                                  "webhook"
                                ],
                                "type": "string",
                                "const": "webhook"
                              },
                              "mode": {
                                "type": "string",
                                "const": "sequence"
                              },
                              "responses": {
                                "examples": [
                                  [
                                    {
                                      "status": 400,
                                      "body": {
                                        "error": "CEP inválido"
                                      }
                                    },
                                    {
                                      "status": 201,
                                      "body": {
                                        "data": {
                                          "status": "AUTORIZADA"
                                        }
                                      }
                                    }
                                  ]
                                ],
                                "minItems": 1,
                                "type": "array",
                                "items": {
                                  "anyOf": [
                                    {
                                      "type": "object",
                                      "properties": {
                                        "status": {
                                          "examples": [
                                            200
                                          ],
                                          "type": "integer",
                                          "minimum": 100,
                                          "maximum": 599
                                        },
                                        "headers": {
                                          "examples": [
                                            {
                                              "content-type": "application/json"
                                            }
                                          ],
                                          "type": "object",
                                          "propertyNames": {
                                            "type": "string"
                                          },
                                          "additionalProperties": {
                                            "type": "string"
                                          }
                                        },
                                        "body": {
                                          "examples": [
                                            {
                                              "orderStatus": "shipped"
                                            }
                                          ],
                                          "$ref": "#/components/schemas/getAgentEvalMockBaseline_schema0"
                                        },
                                        "noResponse": {
                                          "not": {}
                                        }
                                      },
                                      "required": [
                                        "status"
                                      ],
                                      "additionalProperties": false
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "noResponse": {
                                          "examples": [
                                            true
                                          ],
                                          "type": "boolean",
                                          "const": true
                                        },
                                        "error": {
                                          "examples": [
                                            "connect ECONNREFUSED 10.0.0.4:443"
                                          ],
                                          "type": "string"
                                        },
                                        "status": {
                                          "not": {}
                                        }
                                      },
                                      "required": [
                                        "noResponse"
                                      ],
                                      "additionalProperties": false
                                    }
                                  ]
                                }
                              }
                            },
                            "required": [
                              "type",
                              "mode",
                              "responses"
                            ],
                            "additionalProperties": false
                          }
                        ]
                      }
                    },
                    "createdAt": {
                      "description": "ISO 8601 creation timestamp.",
                      "examples": [
                        "2026-08-18T09:00:00.000Z"
                      ],
                      "type": "string"
                    },
                    "updatedAt": {
                      "description": "ISO 8601 timestamp of the last update.",
                      "examples": [
                        "2026-08-18T09:00:00.000Z"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "agentId",
                    "applicationId",
                    "mocks",
                    "createdAt",
                    "updatedAt"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "The agent has no baseline",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "upsertAgentEvalMockBaseline",
        "summary": "Replace the baseline node mocks of an agent",
        "tags": [
          "agent-testing"
        ],
        "description": "Baseline node mocks are the fallback underneath every eval of this agent. When an eval runs, its own `nodeMocks` win per node id and the baseline answers for the rest. An agent without a baseline behaves exactly as it did before baselines existed: a node with no mock performs a real webhook call. This replaces the whole set rather than patching it. Every node id must exist somewhere in the agent tree, including sub-agent workflows; unknown ids are rejected.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application to scope the request to. Omit to use the company-wide scope.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "applicationId": {
                    "description": "Id of the application used to validate access. Omit to validate company-wide access.",
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  "mocks": {
                    "description": "The complete set of baseline node mocks, keyed by node id. Replaces whatever the agent had before — this is a PUT, not a patch. Every node id must exist somewhere in the agent tree.",
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "examples": [
                                "webhook"
                              ],
                              "type": "string",
                              "const": "webhook"
                            },
                            "mode": {
                              "default": "staticResponse",
                              "type": "string",
                              "const": "staticResponse"
                            },
                            "response": {
                              "anyOf": [
                                {
                                  "type": "object",
                                  "properties": {
                                    "status": {
                                      "examples": [
                                        200
                                      ],
                                      "type": "integer",
                                      "minimum": 100,
                                      "maximum": 599
                                    },
                                    "headers": {
                                      "examples": [
                                        {
                                          "content-type": "application/json"
                                        }
                                      ],
                                      "type": "object",
                                      "propertyNames": {
                                        "type": "string"
                                      },
                                      "additionalProperties": {
                                        "type": "string"
                                      }
                                    },
                                    "body": {
                                      "examples": [
                                        {
                                          "orderStatus": "shipped"
                                        }
                                      ],
                                      "$ref": "#/components/schemas/upsertAgentEvalMockBaseline_schema0"
                                    },
                                    "noResponse": {
                                      "not": {}
                                    }
                                  },
                                  "required": [
                                    "status"
                                  ]
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "noResponse": {
                                      "examples": [
                                        true
                                      ],
                                      "type": "boolean",
                                      "const": true
                                    },
                                    "error": {
                                      "examples": [
                                        "connect ECONNREFUSED 10.0.0.4:443"
                                      ],
                                      "type": "string"
                                    },
                                    "status": {
                                      "not": {}
                                    }
                                  },
                                  "required": [
                                    "noResponse"
                                  ]
                                }
                              ]
                            }
                          },
                          "required": [
                            "type",
                            "response"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "examples": [
                                "webhook"
                              ],
                              "type": "string",
                              "const": "webhook"
                            },
                            "mode": {
                              "type": "string",
                              "const": "sequence"
                            },
                            "responses": {
                              "examples": [
                                [
                                  {
                                    "status": 400,
                                    "body": {
                                      "error": "CEP inválido"
                                    }
                                  },
                                  {
                                    "status": 201,
                                    "body": {
                                      "data": {
                                        "status": "AUTORIZADA"
                                      }
                                    }
                                  }
                                ]
                              ],
                              "minItems": 1,
                              "type": "array",
                              "items": {
                                "anyOf": [
                                  {
                                    "type": "object",
                                    "properties": {
                                      "status": {
                                        "examples": [
                                          200
                                        ],
                                        "type": "integer",
                                        "minimum": 100,
                                        "maximum": 599
                                      },
                                      "headers": {
                                        "examples": [
                                          {
                                            "content-type": "application/json"
                                          }
                                        ],
                                        "type": "object",
                                        "propertyNames": {
                                          "type": "string"
                                        },
                                        "additionalProperties": {
                                          "type": "string"
                                        }
                                      },
                                      "body": {
                                        "examples": [
                                          {
                                            "orderStatus": "shipped"
                                          }
                                        ],
                                        "$ref": "#/components/schemas/upsertAgentEvalMockBaseline_schema0"
                                      },
                                      "noResponse": {
                                        "not": {}
                                      }
                                    },
                                    "required": [
                                      "status"
                                    ]
                                  },
                                  {
                                    "type": "object",
                                    "properties": {
                                      "noResponse": {
                                        "examples": [
                                          true
                                        ],
                                        "type": "boolean",
                                        "const": true
                                      },
                                      "error": {
                                        "examples": [
                                          "connect ECONNREFUSED 10.0.0.4:443"
                                        ],
                                        "type": "string"
                                      },
                                      "status": {
                                        "not": {}
                                      }
                                    },
                                    "required": [
                                      "noResponse"
                                    ]
                                  }
                                ]
                              }
                            }
                          },
                          "required": [
                            "type",
                            "mode",
                            "responses"
                          ]
                        }
                      ]
                    }
                  }
                },
                "required": [
                  "mocks"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The saved baseline",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "The baseline's unique id.",
                      "examples": [
                        "cmc3k7f1a0002l608q9d2xk41"
                      ],
                      "type": "string"
                    },
                    "agentId": {
                      "description": "Id of the agent the baseline belongs to.",
                      "examples": [
                        "cmc3k1x9d0001l608r2vhq7e2"
                      ],
                      "type": "string"
                    },
                    "applicationId": {
                      "description": "Id of the application the baseline is scoped to, or null.",
                      "examples": [
                        42
                      ],
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "mocks": {
                      "description": "Node mocks every eval of this agent inherits, keyed by node id. Same shape as an eval spec’s `nodeMocks`.",
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {
                        "anyOf": [
                          {
                            "type": "object",
                            "properties": {
                              "type": {
                                "examples": [
                                  "webhook"
                                ],
                                "type": "string",
                                "const": "webhook"
                              },
                              "mode": {
                                "default": "staticResponse",
                                "type": "string",
                                "const": "staticResponse"
                              },
                              "response": {
                                "anyOf": [
                                  {
                                    "type": "object",
                                    "properties": {
                                      "status": {
                                        "examples": [
                                          200
                                        ],
                                        "type": "integer",
                                        "minimum": 100,
                                        "maximum": 599
                                      },
                                      "headers": {
                                        "examples": [
                                          {
                                            "content-type": "application/json"
                                          }
                                        ],
                                        "type": "object",
                                        "propertyNames": {
                                          "type": "string"
                                        },
                                        "additionalProperties": {
                                          "type": "string"
                                        }
                                      },
                                      "body": {
                                        "examples": [
                                          {
                                            "orderStatus": "shipped"
                                          }
                                        ],
                                        "$ref": "#/components/schemas/upsertAgentEvalMockBaseline_schema0_2"
                                      },
                                      "noResponse": {
                                        "not": {}
                                      }
                                    },
                                    "required": [
                                      "status"
                                    ],
                                    "additionalProperties": false
                                  },
                                  {
                                    "type": "object",
                                    "properties": {
                                      "noResponse": {
                                        "examples": [
                                          true
                                        ],
                                        "type": "boolean",
                                        "const": true
                                      },
                                      "error": {
                                        "examples": [
                                          "connect ECONNREFUSED 10.0.0.4:443"
                                        ],
                                        "type": "string"
                                      },
                                      "status": {
                                        "not": {}
                                      }
                                    },
                                    "required": [
                                      "noResponse"
                                    ],
                                    "additionalProperties": false
                                  }
                                ]
                              }
                            },
                            "required": [
                              "type",
                              "mode",
                              "response"
                            ],
                            "additionalProperties": false
                          },
                          {
                            "type": "object",
                            "properties": {
                              "type": {
                                "examples": [
                                  "webhook"
                                ],
                                "type": "string",
                                "const": "webhook"
                              },
                              "mode": {
                                "type": "string",
                                "const": "sequence"
                              },
                              "responses": {
                                "examples": [
                                  [
                                    {
                                      "status": 400,
                                      "body": {
                                        "error": "CEP inválido"
                                      }
                                    },
                                    {
                                      "status": 201,
                                      "body": {
                                        "data": {
                                          "status": "AUTORIZADA"
                                        }
                                      }
                                    }
                                  ]
                                ],
                                "minItems": 1,
                                "type": "array",
                                "items": {
                                  "anyOf": [
                                    {
                                      "type": "object",
                                      "properties": {
                                        "status": {
                                          "examples": [
                                            200
                                          ],
                                          "type": "integer",
                                          "minimum": 100,
                                          "maximum": 599
                                        },
                                        "headers": {
                                          "examples": [
                                            {
                                              "content-type": "application/json"
                                            }
                                          ],
                                          "type": "object",
                                          "propertyNames": {
                                            "type": "string"
                                          },
                                          "additionalProperties": {
                                            "type": "string"
                                          }
                                        },
                                        "body": {
                                          "examples": [
                                            {
                                              "orderStatus": "shipped"
                                            }
                                          ],
                                          "$ref": "#/components/schemas/upsertAgentEvalMockBaseline_schema0_2"
                                        },
                                        "noResponse": {
                                          "not": {}
                                        }
                                      },
                                      "required": [
                                        "status"
                                      ],
                                      "additionalProperties": false
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "noResponse": {
                                          "examples": [
                                            true
                                          ],
                                          "type": "boolean",
                                          "const": true
                                        },
                                        "error": {
                                          "examples": [
                                            "connect ECONNREFUSED 10.0.0.4:443"
                                          ],
                                          "type": "string"
                                        },
                                        "status": {
                                          "not": {}
                                        }
                                      },
                                      "required": [
                                        "noResponse"
                                      ],
                                      "additionalProperties": false
                                    }
                                  ]
                                }
                              }
                            },
                            "required": [
                              "type",
                              "mode",
                              "responses"
                            ],
                            "additionalProperties": false
                          }
                        ]
                      }
                    },
                    "createdAt": {
                      "description": "ISO 8601 creation timestamp.",
                      "examples": [
                        "2026-08-18T09:00:00.000Z"
                      ],
                      "type": "string"
                    },
                    "updatedAt": {
                      "description": "ISO 8601 timestamp of the last update.",
                      "examples": [
                        "2026-08-18T09:00:00.000Z"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "agentId",
                    "applicationId",
                    "mocks",
                    "createdAt",
                    "updatedAt"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "Invalid mocks or unknown node id",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteAgentEvalMockBaseline",
        "summary": "Delete the baseline node mocks of an agent",
        "tags": [
          "agent-testing"
        ],
        "description": "Removes the baseline. Evals of this agent fall back to their own `nodeMocks`, and any node neither of them mocks performs a real webhook call again. Succeeds even when there was no baseline.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application to scope the request to. Omit to use the company-wide scope.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "204": {
            "description": "The baseline was removed"
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/test-runs/": {
      "get": {
        "operationId": "listAgentTestRuns",
        "summary": "List the test runs of an agent",
        "tags": [
          "agent-testing"
        ],
        "description": "`page` is 1-indexed. `limit` is a legacy alias for `pageSize`; invalid or non-positive values fall back to the defaults (page 1, pageSize 10). `fields=full` opts into the heavy payload (per-step results, untruncated reason); anything else keeps the compact projection.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Only return runs scoped to this application.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "testCaseId",
            "in": "query",
            "required": false,
            "description": "Only return runs of this test case.",
            "schema": {
              "examples": [
                "cmc3k5r2b0004l608w1t8fmz9"
              ]
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-indexed page number. Invalid or non-positive values fall back to 1.",
            "schema": {
              "examples": [
                "1"
              ],
              "type": "string"
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "required": false,
            "description": "Number of runs per page. Invalid or non-positive values fall back to 10.",
            "schema": {
              "examples": [
                "25"
              ],
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Legacy alias for `pageSize`, used when `pageSize` is absent.",
            "schema": {
              "examples": [
                "25"
              ],
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Only return runs with these statuses: `QUEUED`, `RUNNING`, `COMPLETED`, or `ERROR`. Repeatable.",
            "schema": {
              "examples": [
                "COMPLETED"
              ]
            }
          },
          {
            "name": "failedOutcomesOnly",
            "in": "query",
            "required": false,
            "description": "Pass `1` or `true` to only return failed outcomes: runs with status `ERROR` or completed runs that did not pass. Takes precedence over `status`.",
            "schema": {
              "examples": [
                "true"
              ]
            }
          },
          {
            "name": "fields",
            "in": "query",
            "required": false,
            "description": "`full` includes per-step results and the untruncated failure reason. Any other value keeps the compact projection.",
            "schema": {
              "examples": [
                "full"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "One page of test runs with the total row count",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "rows": {
                      "description": "The runs of the requested page, newest first.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "The test run's unique id.",
                            "examples": [
                              "cmc3k9p7f0007l608u3jdx4a1"
                            ],
                            "type": "string"
                          },
                          "applicationId": {
                            "description": "Id of the application the run is scoped to, or null.",
                            "examples": [
                              42
                            ],
                            "anyOf": [
                              {
                                "type": "number"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "agentId": {
                            "description": "Id of the agent the run belongs to.",
                            "examples": [
                              "cmc3k1x9d0001l608r2vhq7e2"
                            ],
                            "type": "string"
                          },
                          "testCaseId": {
                            "description": "Id of the test case that produced this run.",
                            "examples": [
                              "cmc3k5r2b0004l608w1t8fmz9"
                            ],
                            "type": "string"
                          },
                          "status": {
                            "description": "The run status: `QUEUED`, `RUNNING`, `COMPLETED`, or `ERROR`. Runs stopped by the user end as `ERROR` with the reason \"Cancelled by user\".",
                            "examples": [
                              "COMPLETED"
                            ],
                            "type": "string"
                          },
                          "passed": {
                            "description": "Whether the run passed all assertions. Null while the run is still running.",
                            "examples": [
                              true
                            ],
                            "anyOf": [
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "reason": {
                            "description": "Failure or cancellation detail, or null. Truncated to 500 characters in the compact list projection.",
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "threadId": {
                            "description": "Id of the conversation thread the test executed in, or null.",
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "startedAt": {
                            "description": "ISO 8601 timestamp when the run started.",
                            "examples": [
                              "2026-07-01T12:30:00.000Z"
                            ],
                            "type": "string"
                          },
                          "finishedAt": {
                            "description": "ISO 8601 timestamp when the run finished, or null while it is still running.",
                            "examples": [
                              "2026-07-01T12:31:10.000Z"
                            ],
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "createdAt": {
                            "description": "ISO 8601 creation timestamp.",
                            "examples": [
                              "2026-07-01T12:30:00.000Z"
                            ],
                            "type": "string"
                          },
                          "updatedAt": {
                            "description": "ISO 8601 timestamp of the last update.",
                            "examples": [
                              "2026-07-01T12:31:10.000Z"
                            ],
                            "type": "string"
                          },
                          "score": {
                            "description": "Mean smartAssertion judge score of the representative attempt (0-10), or null.",
                            "anyOf": [
                              {
                                "type": "number"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "passRate": {
                            "description": "Fraction of judged attempts that passed, or null.",
                            "anyOf": [
                              {
                                "type": "number"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "repeats": {
                            "description": "Number of attempts requested for this run.",
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "attemptResults": {
                            "description": "Compact per-attempt summaries. Only returned by the run detail endpoint.",
                            "anyOf": [
                              {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "attempt": {
                                      "description": "1-based attempt number.",
                                      "type": "integer",
                                      "minimum": -9007199254740991,
                                      "maximum": 9007199254740991
                                    },
                                    "passed": {
                                      "anyOf": [
                                        {
                                          "type": "boolean"
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    },
                                    "score": {
                                      "anyOf": [
                                        {
                                          "type": "number"
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    },
                                    "threadId": {
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "attempt",
                                    "passed",
                                    "score"
                                  ],
                                  "additionalProperties": {}
                                }
                              },
                              {
                                "type": "null"
                              }
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "applicationId",
                          "agentId",
                          "testCaseId",
                          "status",
                          "passed",
                          "reason",
                          "threadId",
                          "startedAt",
                          "finishedAt",
                          "createdAt",
                          "updatedAt"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "totalCount": {
                      "description": "Total number of runs matching the filters, across all pages.",
                      "examples": [
                        137
                      ],
                      "type": "number"
                    },
                    "fields": {
                      "description": "The projection that was applied to the rows.",
                      "examples": [
                        "compact"
                      ],
                      "type": "string",
                      "enum": [
                        "compact",
                        "full"
                      ]
                    },
                    "pageSize": {
                      "description": "The page size that was applied.",
                      "examples": [
                        10
                      ],
                      "type": "number"
                    }
                  },
                  "required": [
                    "rows",
                    "totalCount",
                    "fields",
                    "pageSize"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/test-runs/trend/": {
      "get": {
        "operationId": "getAgentTestRunTrend",
        "summary": "Get the daily score trend of an agent’s eval suite",
        "tags": [
          "agent-testing"
        ],
        "description": "Returns one point per UTC day that has at least one completed, scored run, oldest first, with the mean score and pass rate of that day. Days with runs but nothing scorable produce no point. Advisory evals never feed the average; `advisoryTestCaseCount` reports how many were excluded. `days` defaults to 30 and is capped at 90.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Only aggregate runs scoped to this application.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "description": "How many days back the trend reaches. Defaults to 30 and is capped at 90; invalid values fall back to the default.",
            "schema": {
              "examples": [
                30
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The daily score trend of the suite",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "days": {
                      "description": "The window that was applied, after defaulting and capping.",
                      "examples": [
                        30
                      ],
                      "type": "number"
                    },
                    "points": {
                      "description": "One point per day that has at least one scored run, oldest first.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "day": {
                            "description": "UTC calendar day of the point.",
                            "examples": [
                              "2026-08-10"
                            ],
                            "type": "string"
                          },
                          "runCount": {
                            "description": "Scored runs that went into this day’s average.",
                            "examples": [
                              12
                            ],
                            "type": "number"
                          },
                          "averageScore": {
                            "description": "Mean 0-10 score of the day.",
                            "examples": [
                              7.5
                            ],
                            "type": "number"
                          },
                          "passedRunCount": {
                            "description": "Runs of the day that passed.",
                            "examples": [
                              9
                            ],
                            "type": "number"
                          },
                          "passRatePercent": {
                            "description": "0-100 share of the day’s runs that passed.",
                            "examples": [
                              75
                            ],
                            "type": "number"
                          }
                        },
                        "required": [
                          "day",
                          "runCount",
                          "averageScore",
                          "passedRunCount",
                          "passRatePercent"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "gatingTestCaseCount": {
                      "description": "Evals whose runs feed the aggregate.",
                      "examples": [
                        6
                      ],
                      "type": "number"
                    },
                    "advisoryTestCaseCount": {
                      "description": "Evals left out of the aggregate because they are advisory.",
                      "examples": [
                        1
                      ],
                      "type": "number"
                    }
                  },
                  "required": [
                    "days",
                    "points",
                    "gatingTestCaseCount",
                    "advisoryTestCaseCount"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/test-runs/{runId}/": {
      "get": {
        "operationId": "getAgentTestRun",
        "summary": "Get a test run of an agent",
        "tags": [
          "agent-testing"
        ],
        "description": "Returns the full run, including `stepResults` with the per-step outcomes, the parent test case id and name, and an `overallScore` averaged from the smart assertion scores. While `status` is `RUNNING`, `passed` and `finishedAt` are null, so poll this endpoint until the run finishes. The `applicationId` query parameter is optional: when omitted, it is derived from the run itself.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "description": "The test run's unique id.",
            "schema": {
              "examples": [
                "cmc3k9p7f0007l608u3jdx4a1"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application the test run belongs to. When omitted, it is derived from the run itself; when given, the run must belong to that application.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The test run",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "The test run's unique id.",
                      "examples": [
                        "cmc3k9p7f0007l608u3jdx4a1"
                      ],
                      "type": "string"
                    },
                    "applicationId": {
                      "description": "Id of the application the run is scoped to, or null.",
                      "examples": [
                        42
                      ],
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "agentId": {
                      "description": "Id of the agent the run belongs to.",
                      "examples": [
                        "cmc3k1x9d0001l608r2vhq7e2"
                      ],
                      "type": "string"
                    },
                    "testCaseId": {
                      "description": "Id of the test case that produced this run.",
                      "examples": [
                        "cmc3k5r2b0004l608w1t8fmz9"
                      ],
                      "type": "string"
                    },
                    "status": {
                      "description": "The run status: `QUEUED`, `RUNNING`, `COMPLETED`, or `ERROR`. Runs stopped by the user end as `ERROR` with the reason \"Cancelled by user\".",
                      "examples": [
                        "COMPLETED"
                      ],
                      "type": "string"
                    },
                    "passed": {
                      "description": "Whether the run passed all assertions. Null while the run is still running.",
                      "examples": [
                        true
                      ],
                      "anyOf": [
                        {
                          "type": "boolean"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "reason": {
                      "description": "Failure or cancellation detail, or null. Truncated to 500 characters in the compact list projection.",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "threadId": {
                      "description": "Id of the conversation thread the test executed in, or null.",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "startedAt": {
                      "description": "ISO 8601 timestamp when the run started.",
                      "examples": [
                        "2026-07-01T12:30:00.000Z"
                      ],
                      "type": "string"
                    },
                    "finishedAt": {
                      "description": "ISO 8601 timestamp when the run finished, or null while it is still running.",
                      "examples": [
                        "2026-07-01T12:31:10.000Z"
                      ],
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "createdAt": {
                      "description": "ISO 8601 creation timestamp.",
                      "examples": [
                        "2026-07-01T12:30:00.000Z"
                      ],
                      "type": "string"
                    },
                    "updatedAt": {
                      "description": "ISO 8601 timestamp of the last update.",
                      "examples": [
                        "2026-07-01T12:31:10.000Z"
                      ],
                      "type": "string"
                    },
                    "score": {
                      "description": "Mean smartAssertion judge score of the representative attempt (0-10), or null.",
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "passRate": {
                      "description": "Fraction of judged attempts that passed, or null.",
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "repeats": {
                      "description": "Number of attempts requested for this run.",
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "attemptResults": {
                      "description": "Compact per-attempt summaries. Only returned by the run detail endpoint.",
                      "anyOf": [
                        {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "attempt": {
                                "description": "1-based attempt number.",
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991
                              },
                              "passed": {
                                "anyOf": [
                                  {
                                    "type": "boolean"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "score": {
                                "anyOf": [
                                  {
                                    "type": "number"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "threadId": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "attempt",
                              "passed",
                              "score"
                            ],
                            "additionalProperties": {}
                          }
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "applicationId",
                    "agentId",
                    "testCaseId",
                    "status",
                    "passed",
                    "reason",
                    "threadId",
                    "startedAt",
                    "finishedAt",
                    "createdAt",
                    "updatedAt"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Test run not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteAgentTestRun",
        "summary": "Delete a test run of an agent",
        "tags": [
          "agent-testing"
        ],
        "description": "Permanently removes the run and its recorded results. The run must belong to the agent in the path. The `applicationId` query parameter is optional: when omitted, it is derived from the run itself.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "description": "The test run's unique id.",
            "schema": {
              "examples": [
                "cmc3k9p7f0007l608u3jdx4a1"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application the test run belongs to. When omitted, it is derived from the run itself; when given, the run must belong to that application.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The test run was deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "success",
                    "message"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid applicationId, or the agent needs an explicit application scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Test run not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/test-runs/{runId}/stop/": {
      "post": {
        "operationId": "stopAgentTestRun",
        "summary": "Stop a queued or running test run of an agent",
        "tags": [
          "agent-testing"
        ],
        "description": "Runs with status `QUEUED` or `RUNNING` can be stopped; a queued run is cancelled before the worker ever claims it. Stopping aborts the agent executions of the run thread, then marks the run as `ERROR` with the reason `Cancelled by user`. The terminal write is a compare-and-set: if the run finishes first, the response is `409` and the completed result stands. The `applicationId` query parameter is optional: when omitted, it is derived from the run itself.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "description": "The test run's unique id.",
            "schema": {
              "examples": [
                "cmc3k9p7f0007l608u3jdx4a1"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application the test run belongs to. When omitted, it is derived from the run itself; when given, the run must belong to that application.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The test run was cancelled",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the run was cancelled.",
                      "examples": [
                        true
                      ],
                      "type": "boolean"
                    },
                    "message": {
                      "description": "Human readable confirmation.",
                      "examples": [
                        "Test run cancelled successfully"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "success",
                    "message"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid applicationId or run is already terminal",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Test run not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "409": {
            "description": "The run reached a terminal state before it could be cancelled",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/eval-coverage/": {
      "get": {
        "operationId": "getAgentEvalCoverage",
        "summary": "Get how much of an agent’s workflow its eval suite exercises",
        "tags": [
          "agent-testing"
        ],
        "description": "Returns coverage across three layers — workflow nodes (also broken down by node type), declared transitions, and decision criteria — as covered/total plus the ids never reached. Advisory evals count, because they execute for real. Criteria on decision nodes whose transitions never route on a named criterion score cannot be attributed to a fired transition and are reported separately, excluded from both sides of the ratio.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Scope the agent lookup to this application.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Coverage of the agent’s eval suite",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "structuralHash": {
                      "description": "Identity of the graph these numbers describe.",
                      "examples": [
                        "sha256:1a2b…"
                      ],
                      "type": "string"
                    },
                    "nodes": {
                      "type": "object",
                      "properties": {
                        "covered": {
                          "description": "Declared items the suite reached.",
                          "examples": [
                            65
                          ],
                          "type": "number"
                        },
                        "total": {
                          "description": "Items the spec declares.",
                          "examples": [
                            96
                          ],
                          "type": "number"
                        },
                        "uncovered": {
                          "description": "Nodes never executed — the test backlog, sorted by id.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "description": "The workflow node id the metric keys on.",
                                "examples": [
                                  "n-06ddxtqtg"
                                ],
                                "type": "string"
                              },
                              "name": {
                                "description": "The node’s label, falling back to its id.",
                                "examples": [
                                  "Ask for the CNPJ"
                                ],
                                "type": "string"
                              },
                              "nodeType": {
                                "description": "decision, action, subAgent, end, …",
                                "examples": [
                                  "action"
                                ],
                                "type": "string"
                              },
                              "actionType": {
                                "description": "Action nodes only — the context that makes an unlabelled node legible.",
                                "examples": [
                                  "WEBHOOK"
                                ],
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "name",
                              "nodeType"
                            ],
                            "additionalProperties": false
                          }
                        },
                        "byType": {
                          "description": "The same figures per node type.",
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "object",
                            "properties": {
                              "covered": {
                                "description": "Declared items the suite reached.",
                                "examples": [
                                  65
                                ],
                                "type": "number"
                              },
                              "total": {
                                "description": "Items the spec declares.",
                                "examples": [
                                  96
                                ],
                                "type": "number"
                              },
                              "uncovered": {
                                "description": "Nodes never executed — the test backlog, sorted by id.",
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "description": "The workflow node id the metric keys on.",
                                      "examples": [
                                        "n-06ddxtqtg"
                                      ],
                                      "type": "string"
                                    },
                                    "name": {
                                      "description": "The node’s label, falling back to its id.",
                                      "examples": [
                                        "Ask for the CNPJ"
                                      ],
                                      "type": "string"
                                    },
                                    "nodeType": {
                                      "description": "decision, action, subAgent, end, …",
                                      "examples": [
                                        "action"
                                      ],
                                      "type": "string"
                                    },
                                    "actionType": {
                                      "description": "Action nodes only — the context that makes an unlabelled node legible.",
                                      "examples": [
                                        "WEBHOOK"
                                      ],
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "name",
                                    "nodeType"
                                  ],
                                  "additionalProperties": false
                                }
                              }
                            },
                            "required": [
                              "covered",
                              "total",
                              "uncovered"
                            ],
                            "additionalProperties": false
                          }
                        }
                      },
                      "required": [
                        "covered",
                        "total",
                        "uncovered",
                        "byType"
                      ],
                      "additionalProperties": false
                    },
                    "transitions": {
                      "type": "object",
                      "properties": {
                        "covered": {
                          "description": "Declared items the suite reached.",
                          "examples": [
                            65
                          ],
                          "type": "number"
                        },
                        "total": {
                          "description": "Items the spec declares.",
                          "examples": [
                            96
                          ],
                          "type": "number"
                        },
                        "uncovered": {
                          "description": "Arrows never fired, sorted by id.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "description": "`<sourceNodeId>#<declarationIndex>`.",
                                "examples": [
                                  "n-ret2dados#0"
                                ],
                                "type": "string"
                              },
                              "fromName": {
                                "description": "Name of the node the arrow leaves.",
                                "examples": [
                                  "Triage"
                                ],
                                "type": "string"
                              },
                              "toName": {
                                "description": "Name of the node the arrow targets.",
                                "examples": [
                                  "Send the quote"
                                ],
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "fromName",
                              "toName"
                            ],
                            "additionalProperties": false
                          }
                        }
                      },
                      "required": [
                        "covered",
                        "total",
                        "uncovered"
                      ],
                      "additionalProperties": false
                    },
                    "criteria": {
                      "type": "object",
                      "properties": {
                        "covered": {
                          "description": "Declared items the suite reached.",
                          "examples": [
                            65
                          ],
                          "type": "number"
                        },
                        "total": {
                          "description": "Items the spec declares.",
                          "examples": [
                            96
                          ],
                          "type": "number"
                        },
                        "uncovered": {
                          "description": "Criteria that were never the reason an arrow fired.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "examples": [
                                  "ckv9…"
                                ],
                                "type": "string"
                              },
                              "name": {
                                "description": "The criterion’s name, falling back to its id.",
                                "examples": [
                                  "Wants a quote"
                                ],
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "name"
                            ],
                            "additionalProperties": false
                          }
                        },
                        "notAttributable": {
                          "description": "Criteria on decision nodes whose transitions never route on a named criterion score, so no fired arrow can be attributed to them. Excluded from both sides of the ratio.",
                          "type": "object",
                          "properties": {
                            "criteriaIds": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "decisionNodeIds": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            }
                          },
                          "required": [
                            "criteriaIds",
                            "decisionNodeIds"
                          ],
                          "additionalProperties": false
                        }
                      },
                      "required": [
                        "covered",
                        "total",
                        "uncovered",
                        "notAttributable"
                      ],
                      "additionalProperties": false
                    },
                    "contributingRuns": {
                      "description": "Runs whose graph matched the current spec.",
                      "examples": [
                        34
                      ],
                      "type": "number"
                    },
                    "enabledEvals": {
                      "description": "Enabled evals in the suite.",
                      "examples": [
                        101
                      ],
                      "type": "number"
                    }
                  },
                  "required": [
                    "structuralHash",
                    "nodes",
                    "transitions",
                    "criteria",
                    "contributingRuns",
                    "enabledEvals"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/executions/": {
      "get": {
        "operationId": "listAgentExecutions",
        "summary": "List the executions of an agent",
        "tags": [
          "agent-executions"
        ],
        "description": "`fields=full` opts into the heavy message payload; `fields=vars` adds the final agent state variables without the heavy message content; anything else keeps the compact projection. `statuses` is a comma-separated list.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application the agent runs in. When omitted, it is derived from the agent itself.",
            "schema": {
              "examples": [
                "42"
              ],
              "type": "string"
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search across execution id, thread id, message id, message metadata, and the message author name, email, and phone number.",
            "schema": {}
          },
          {
            "name": "searchContent",
            "in": "query",
            "required": false,
            "description": "Pass `true` to also match `search` against message content.",
            "schema": {
              "examples": [
                "true"
              ]
            }
          },
          {
            "name": "executionType",
            "in": "query",
            "required": false,
            "description": "`EVAL` only returns executions from test runs, `LIVE` excludes them. Any other value returns both.",
            "schema": {
              "examples": [
                "LIVE"
              ]
            }
          },
          {
            "name": "hasErrors",
            "in": "query",
            "required": false,
            "description": "Pass `true` to only return executions that recorded errors.",
            "schema": {
              "examples": [
                "true"
              ]
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-indexed page number. Defaults to 1.",
            "schema": {
              "examples": [
                "1"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Number of executions per page. Defaults to 50.",
            "schema": {
              "examples": [
                "50"
              ]
            }
          },
          {
            "name": "statuses",
            "in": "query",
            "required": false,
            "description": "Comma-separated list of statuses to include: `RUNNING`, `STOPPED`, `FINISHED`, `STALLED` or `TIMED_OUT`.",
            "schema": {
              "examples": [
                "RUNNING,FINISHED"
              ]
            }
          },
          {
            "name": "createdFrom",
            "in": "query",
            "required": false,
            "description": "Only return executions created at or after this ISO 8601 timestamp.",
            "schema": {
              "examples": [
                "2026-07-01T00:00:00.000Z"
              ]
            }
          },
          {
            "name": "createdTo",
            "in": "query",
            "required": false,
            "description": "Only return executions created at or before this ISO 8601 timestamp.",
            "schema": {
              "examples": [
                "2026-07-08T23:59:59.000Z"
              ]
            }
          },
          {
            "name": "fields",
            "in": "query",
            "required": false,
            "description": "`full` includes the heavy message content and metadata, `vars` adds the final agent state variables without the message content. Any other value keeps the compact projection.",
            "schema": {
              "examples": [
                "compact"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "One page of executions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "executions": {
                      "description": "One page of executions, newest first, shaped by the `fields` projection.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "The execution's unique id.",
                            "examples": [
                              "exec_01j9z3k2b4c5d6e7f8g9h0j1k2"
                            ],
                            "type": "string"
                          }
                        },
                        "required": [
                          "id"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "hasNextPage": {
                      "description": "True when more pages exist after the requested one.",
                      "examples": [
                        true
                      ],
                      "type": "boolean"
                    },
                    "totalCount": {
                      "description": "Total number of executions matching the filters.",
                      "examples": [
                        312
                      ],
                      "type": "number"
                    }
                  },
                  "required": [
                    "executions"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "Invalid applicationId, or the agent needs an explicit application scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Listing failure",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/executions/{executionId}/": {
      "get": {
        "operationId": "getAgentExecution",
        "summary": "Get an execution of an agent",
        "tags": [
          "agent-executions"
        ],
        "description": "Returns the execution detail. Executions that already finished or stopped are served from a cache, running ones are always read fresh, so this endpoint can be polled to track a live execution. The `applicationId` query parameter is optional: when omitted, it is derived from the execution itself. Node detail is progressive: `fields=minimal` (the default) returns a lean, de-duplicated timeline, `fields=compact` keeps full node output minus the repeated debug snapshots, and `fields=full` returns everything; `nodeIds` narrows to specific steps. Document URLs inside node outputs and the input message carry a time-limited `vid` token, so they can be fetched, rendered or attached without platform credentials for a few hours (re-fetch the execution for fresh ones). Use `POST /api/v1/agents/{agentId}/executions/{executionId}/stop/` to cancel a running execution.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "executionId",
            "in": "path",
            "required": true,
            "description": "The execution's unique id.",
            "schema": {
              "examples": [
                "exec_01j9z3k2b4c5d6e7f8g9h0j1k2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application the agent runs in. When omitted, it is derived from the execution itself.",
            "schema": {
              "examples": [
                "42"
              ],
              "type": "string"
            }
          },
          {
            "name": "fields",
            "in": "query",
            "required": false,
            "description": "Response projection, from leanest to fullest — read minimal first, then pull more only where needed. `minimal` (the default) drops each node’s heavy `input.context` and de-duplicates the decision evaluation (a decision node otherwise repeats its results four ways and inlines every criterion prompt); it keeps per-node identity, status, the transition taken, and a lean output. `compact` keeps the full output but strips only `input.context.executedNodeOutputs`. `full` returns nodes exactly as stored. Combine any of these with `nodeIds` to return just the nodes you care about.",
            "schema": {
              "examples": [
                "minimal"
              ],
              "default": "minimal",
              "type": "string",
              "enum": [
                "minimal",
                "compact",
                "full"
              ]
            }
          },
          {
            "name": "nodeIds",
            "in": "query",
            "required": false,
            "description": "Comma-separated node ids. When set, only those executed nodes are returned (in execution order), so a reader can drill into specific steps without pulling the whole timeline.",
            "schema": {
              "examples": [
                "d1,instr-2"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The execution",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "The execution's unique id.",
                      "examples": [
                        "exec_01j9z3k2b4c5d6e7f8g9h0j1k2"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "Invalid applicationId, or the agent needs an explicit application scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Execution not found or not accessible",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/executions/{executionId}/context-sources/": {
      "post": {
        "operationId": "getAgentExecutionContextSources",
        "summary": "Resolve the context sources of an agent execution",
        "tags": [
          "agent-executions"
        ],
        "description": "Accepts a JSON body `{ applicationId, messageIds?, knowledgeIds?, documentIds? }`. Ids of the wrong type are silently dropped; when no valid id remains the empty payload is returned without touching the database.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "executionId",
            "in": "path",
            "required": true,
            "description": "The execution's unique id.",
            "schema": {
              "examples": [
                "exec_01j9z3k2b4c5d6e7f8g9h0j1k2"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "The application scope and the ids to resolve.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "applicationId": {
                    "description": "Id of the application the execution belongs to.",
                    "examples": [
                      42
                    ],
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "messageIds": {
                    "description": "Ids of the thread messages to resolve.",
                    "examples": [
                      [
                        "msg_01j9z3k2b4c5d6e7"
                      ]
                    ],
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "knowledgeIds": {
                    "description": "Ids of the knowledge chunks to resolve.",
                    "examples": [
                      [
                        5817
                      ]
                    ],
                    "type": "array",
                    "items": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    }
                  },
                  "documentIds": {
                    "description": "Ids of the documents to resolve.",
                    "examples": [
                      [
                        904
                      ]
                    ],
                    "type": "array",
                    "items": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    }
                  }
                },
                "required": [
                  "applicationId"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The resolved context sources",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "messages": {
                      "description": "The resolved thread messages, each with role, content, timestamps, and author.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "The message's unique id.",
                            "examples": [
                              "msg_01j9z3k2b4c5d6e7"
                            ],
                            "type": "string"
                          }
                        },
                        "required": [
                          "id"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "knowledge": {
                      "description": "The resolved knowledge chunks, each with content and source document id.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "The knowledge chunk's id.",
                            "examples": [
                              5817
                            ],
                            "type": "number"
                          }
                        },
                        "required": [
                          "id"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "documents": {
                      "description": "The resolved documents, each with file metadata and collection id.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "The document's id.",
                            "examples": [
                              904
                            ],
                            "type": "number"
                          }
                        },
                        "required": [
                          "id"
                        ],
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "messages",
                    "knowledge",
                    "documents"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON body or missing applicationId",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Execution not found or not accessible",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/executions/{executionId}/stop/": {
      "post": {
        "operationId": "stopAgentExecution",
        "summary": "Stop a running execution of an agent",
        "tags": [
          "agent-executions"
        ],
        "description": "Signals the worker running the execution to abort the in-flight run, then flips the persisted status from `RUNNING` to `STOPPED`. This also clears orphaned executions stuck in `RUNNING` after their worker died. Idempotent: stopping an execution that already finished or stopped returns `stopped: false` with `alreadyTerminal: true`. The `applicationId` query parameter is optional: when omitted, it is derived from the execution itself.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's unique id.",
            "schema": {
              "examples": [
                "cmc3k1x9d0001l608r2vhq7e2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "executionId",
            "in": "path",
            "required": true,
            "description": "The execution's unique id.",
            "schema": {
              "examples": [
                "exec_01j9z3k2b4c5d6e7f8g9h0j1k2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application the agent runs in. When omitted, it is derived from the execution itself.",
            "schema": {
              "examples": [
                "42"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The stop outcome (idempotent)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "executionId": {
                      "description": "The execution's unique id.",
                      "examples": [
                        "exec_01j9z3k2b4c5d6e7f8g9h0j1k2"
                      ],
                      "type": "string"
                    },
                    "previousStatus": {
                      "description": "Status of the execution before the stop request.",
                      "examples": [
                        "RUNNING"
                      ],
                      "type": "string"
                    },
                    "status": {
                      "description": "Status of the execution after the stop request.",
                      "examples": [
                        "STOPPED"
                      ],
                      "type": "string"
                    },
                    "stopped": {
                      "description": "True when this request transitioned the execution to `STOPPED`.",
                      "examples": [
                        true
                      ],
                      "type": "boolean"
                    },
                    "alreadyTerminal": {
                      "description": "True when the execution had already finished or been stopped, making the request a no-op.",
                      "examples": [
                        false
                      ],
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "executionId",
                    "previousStatus",
                    "status",
                    "stopped",
                    "alreadyTerminal"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "Invalid applicationId, or the agent needs an explicit application scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Execution not found or not accessible",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/routines/": {
      "get": {
        "operationId": "listAgentRoutines",
        "summary": "List routines of an agent",
        "tags": [
          "agent-routines"
        ],
        "description": "Returns the routines newest first, each with its triggers and run count. The `applicationId` query parameter is optional: when omitted, it is derived from the agent; when given, it must match the application the agent belongs to.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application the routine belongs to. When omitted, it is derived from the routine (or, for the list route, from the agent); when given, the resource must belong to that application.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The routines of the agent, newest first",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "description": "Unique id of the routine.",
                        "examples": [
                          "clx4b2m1e0003mp08w9f6tj5s"
                        ],
                        "type": "string"
                      },
                      "agentId": {
                        "description": "Id of the agent that owns the routine.",
                        "type": "string"
                      },
                      "applicationId": {
                        "description": "Id of the application the agent belongs to.",
                        "examples": [
                          42
                        ],
                        "type": "number"
                      },
                      "name": {
                        "description": "Display name of the routine.",
                        "type": "string"
                      },
                      "prompt": {
                        "description": "Prompt the agent executes on every run.",
                        "type": "string"
                      },
                      "enabled": {
                        "description": "Whether the routine is active.",
                        "type": "boolean"
                      },
                      "triggers": {
                        "description": "Triggers of the routine, including the implicit API trigger.",
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "description": "Unique id of the trigger.",
                              "type": "string"
                            },
                            "type": {
                              "description": "Trigger type: `SCHEDULED`, `API`, or `DOCUMENT_EVENT`.",
                              "examples": [
                                "SCHEDULED"
                              ],
                              "type": "string"
                            },
                            "enabled": {
                              "description": "Whether the trigger is active.",
                              "type": "boolean"
                            }
                          },
                          "required": [
                            "id",
                            "type",
                            "enabled"
                          ],
                          "additionalProperties": {}
                        }
                      }
                    },
                    "required": [
                      "id",
                      "agentId",
                      "applicationId",
                      "name",
                      "prompt",
                      "enabled",
                      "triggers"
                    ],
                    "additionalProperties": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createAgentRoutine",
        "summary": "Create a routine for an agent",
        "tags": [
          "agent-routines"
        ],
        "description": "The routine needs at least one trigger: `SCHEDULED` (cron, at most every 5 minutes), `API` (on demand via `POST /api/v1/agents/{agentId}/routines/{routineId}/run/`) or `DOCUMENT_EVENT` (fires on document import). An enabled API trigger is added automatically when none is given, so every routine can be run on demand. Cloud Scheduler jobs are created for enabled scheduled triggers.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "applicationId": {
                    "description": "Positive integer id of the application that scopes this operation.",
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  "name": {
                    "description": "Display name of the routine.",
                    "examples": [
                      "Daily inbox summary"
                    ],
                    "type": "string",
                    "minLength": 1
                  },
                  "prompt": {
                    "description": "Prompt the agent executes on every run of the routine.",
                    "examples": [
                      "Summarize the support emails that arrived since the last run and post the digest to the team inbox."
                    ],
                    "type": "string",
                    "minLength": 1
                  },
                  "enabled": {
                    "description": "Whether the routine is active. Defaults to true. Disabled routines never fire.",
                    "examples": [
                      true
                    ],
                    "type": "boolean"
                  },
                  "metadata": {
                    "description": "Freeform key-value metadata stored with the routine.",
                    "examples": [
                      {
                        "team": "support"
                      }
                    ],
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {}
                  },
                  "triggers": {
                    "description": "Triggers that fire the routine. At least one is required. An enabled API trigger is added automatically when none is given.",
                    "minItems": 1,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "Id of an existing trigger. Omit to create a new one. On update, existing triggers not listed by id are deleted.",
                          "examples": [
                            "clx9g4t5j000bmp08e7k2qh6m"
                          ],
                          "type": "string"
                        },
                        "type": {
                          "description": "Trigger type. `SCHEDULED` fires on a cron schedule, `API` fires on demand via `POST /api/v1/agents/{agentId}/routines/{routineId}/run/`, `DOCUMENT_EVENT` fires when a document is imported.",
                          "examples": [
                            "SCHEDULED"
                          ],
                          "type": "string",
                          "enum": [
                            "SCHEDULED",
                            "API",
                            "DOCUMENT_EVENT"
                          ]
                        },
                        "enabled": {
                          "description": "Whether the trigger is active. Defaults to true.",
                          "examples": [
                            true
                          ],
                          "type": "boolean"
                        },
                        "cronExpression": {
                          "description": "Cron expression for `SCHEDULED` triggers. Required for that type and must not fire more often than every 5 minutes.",
                          "examples": [
                            "0 9 * * 1"
                          ],
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "collectionIds": {
                          "description": "Collection ids that scope a `DOCUMENT_EVENT` trigger. An empty list matches documents from any collection.",
                          "examples": [
                            [
                              12,
                              34
                            ]
                          ],
                          "type": "array",
                          "items": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          }
                        },
                        "eventName": {
                          "description": "Document event that fires a `DOCUMENT_EVENT` trigger. Only `document.created` is supported and it is the default.",
                          "examples": [
                            "document.created"
                          ],
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "metadata": {
                          "description": "Freeform key-value metadata stored with the trigger.",
                          "examples": [
                            {
                              "source": "ops-dashboard"
                            }
                          ],
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {}
                        }
                      },
                      "required": [
                        "type"
                      ]
                    }
                  }
                },
                "required": [
                  "applicationId",
                  "name",
                  "prompt",
                  "triggers"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created routine",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "Unique id of the routine.",
                      "examples": [
                        "clx4b2m1e0003mp08w9f6tj5s"
                      ],
                      "type": "string"
                    },
                    "agentId": {
                      "description": "Id of the agent that owns the routine.",
                      "type": "string"
                    },
                    "applicationId": {
                      "description": "Id of the application the agent belongs to.",
                      "examples": [
                        42
                      ],
                      "type": "number"
                    },
                    "name": {
                      "description": "Display name of the routine.",
                      "type": "string"
                    },
                    "prompt": {
                      "description": "Prompt the agent executes on every run.",
                      "type": "string"
                    },
                    "enabled": {
                      "description": "Whether the routine is active.",
                      "type": "boolean"
                    },
                    "triggers": {
                      "description": "Triggers of the routine, including the implicit API trigger.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "Unique id of the trigger.",
                            "type": "string"
                          },
                          "type": {
                            "description": "Trigger type: `SCHEDULED`, `API`, or `DOCUMENT_EVENT`.",
                            "examples": [
                              "SCHEDULED"
                            ],
                            "type": "string"
                          },
                          "enabled": {
                            "description": "Whether the trigger is active.",
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "id",
                          "type",
                          "enabled"
                        ],
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "id",
                    "agentId",
                    "applicationId",
                    "name",
                    "prompt",
                    "enabled",
                    "triggers"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "Invalid body",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Agent not found in this application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Routine creation failure",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/routines/{routineId}/": {
      "get": {
        "operationId": "getAgentRoutine",
        "summary": "Get a routine of an agent with its runs",
        "tags": [
          "agent-routines"
        ],
        "description": "Returns the routine together with its triggers and its runs, newest first. Use it to poll the status of runs queued via `POST /api/v1/agents/{agentId}/routines/{routineId}/run/`.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "routineId",
            "in": "path",
            "required": true,
            "description": "Id of the routine.",
            "schema": {
              "examples": [
                "clx4b2m1e0003mp08w9f6tj5s"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application the routine belongs to. When omitted, it is derived from the routine (or, for the list route, from the agent); when given, the resource must belong to that application.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The routine and its runs",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "routine": {
                      "description": "The routine with its triggers.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "Unique id of the routine.",
                          "examples": [
                            "clx4b2m1e0003mp08w9f6tj5s"
                          ],
                          "type": "string"
                        },
                        "agentId": {
                          "description": "Id of the agent that owns the routine.",
                          "type": "string"
                        },
                        "applicationId": {
                          "description": "Id of the application the agent belongs to.",
                          "examples": [
                            42
                          ],
                          "type": "number"
                        },
                        "name": {
                          "description": "Display name of the routine.",
                          "type": "string"
                        },
                        "prompt": {
                          "description": "Prompt the agent executes on every run.",
                          "type": "string"
                        },
                        "enabled": {
                          "description": "Whether the routine is active.",
                          "type": "boolean"
                        },
                        "triggers": {
                          "description": "Triggers of the routine, including the implicit API trigger.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "description": "Unique id of the trigger.",
                                "type": "string"
                              },
                              "type": {
                                "description": "Trigger type: `SCHEDULED`, `API`, or `DOCUMENT_EVENT`.",
                                "examples": [
                                  "SCHEDULED"
                                ],
                                "type": "string"
                              },
                              "enabled": {
                                "description": "Whether the trigger is active.",
                                "type": "boolean"
                              }
                            },
                            "required": [
                              "id",
                              "type",
                              "enabled"
                            ],
                            "additionalProperties": {}
                          }
                        }
                      },
                      "required": [
                        "id",
                        "agentId",
                        "applicationId",
                        "name",
                        "prompt",
                        "enabled",
                        "triggers"
                      ],
                      "additionalProperties": {}
                    },
                    "runs": {
                      "description": "Runs of the routine, newest first.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "Unique id of the run.",
                            "type": "string"
                          },
                          "status": {
                            "description": "Status of the run: `QUEUED`, `RUNNING`, `SUCCESS`, or `ERROR`.",
                            "examples": [
                              "SUCCESS"
                            ],
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "status"
                        ],
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "routine",
                    "runs"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Routine not found or inaccessible",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateAgentRoutine",
        "summary": "Update a routine of an agent",
        "tags": [
          "agent-routines"
        ],
        "description": "Partial update: only the provided fields change. When `triggers` is given it replaces the whole set, entries with an id update that trigger, entries without an id are created, and existing triggers left out of the list are deleted. Cloud Scheduler jobs are reconciled to match the resulting scheduled triggers, disabled ones are paused rather than deleted.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "routineId",
            "in": "path",
            "required": true,
            "description": "Id of the routine.",
            "schema": {
              "examples": [
                "clx4b2m1e0003mp08w9f6tj5s"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "applicationId": {
                    "description": "Positive integer id of the application that scopes this operation.",
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  "name": {
                    "description": "New display name of the routine.",
                    "examples": [
                      "Daily inbox summary"
                    ],
                    "type": "string",
                    "minLength": 1
                  },
                  "prompt": {
                    "description": "New prompt the agent executes on every run.",
                    "examples": [
                      "Summarize the support emails that arrived since the last run and post the digest to the team inbox."
                    ],
                    "type": "string",
                    "minLength": 1
                  },
                  "enabled": {
                    "description": "Enables or disables the routine.",
                    "examples": [
                      true
                    ],
                    "type": "boolean"
                  },
                  "metadata": {
                    "description": "Replaces the routine metadata.",
                    "examples": [
                      {
                        "team": "support"
                      }
                    ],
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {}
                  },
                  "triggers": {
                    "description": "Full replacement set of triggers. Entries with an id update that trigger, entries without an id are created, and existing triggers left out of the list are deleted.",
                    "minItems": 1,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "Id of an existing trigger. Omit to create a new one. On update, existing triggers not listed by id are deleted.",
                          "examples": [
                            "clx9g4t5j000bmp08e7k2qh6m"
                          ],
                          "type": "string"
                        },
                        "type": {
                          "description": "Trigger type. `SCHEDULED` fires on a cron schedule, `API` fires on demand via `POST /api/v1/agents/{agentId}/routines/{routineId}/run/`, `DOCUMENT_EVENT` fires when a document is imported.",
                          "examples": [
                            "SCHEDULED"
                          ],
                          "type": "string",
                          "enum": [
                            "SCHEDULED",
                            "API",
                            "DOCUMENT_EVENT"
                          ]
                        },
                        "enabled": {
                          "description": "Whether the trigger is active. Defaults to true.",
                          "examples": [
                            true
                          ],
                          "type": "boolean"
                        },
                        "cronExpression": {
                          "description": "Cron expression for `SCHEDULED` triggers. Required for that type and must not fire more often than every 5 minutes.",
                          "examples": [
                            "0 9 * * 1"
                          ],
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "collectionIds": {
                          "description": "Collection ids that scope a `DOCUMENT_EVENT` trigger. An empty list matches documents from any collection.",
                          "examples": [
                            [
                              12,
                              34
                            ]
                          ],
                          "type": "array",
                          "items": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          }
                        },
                        "eventName": {
                          "description": "Document event that fires a `DOCUMENT_EVENT` trigger. Only `document.created` is supported and it is the default.",
                          "examples": [
                            "document.created"
                          ],
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "metadata": {
                          "description": "Freeform key-value metadata stored with the trigger.",
                          "examples": [
                            {
                              "source": "ops-dashboard"
                            }
                          ],
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {}
                        }
                      },
                      "required": [
                        "type"
                      ]
                    }
                  }
                },
                "required": [
                  "applicationId"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated routine",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "Unique id of the routine.",
                      "examples": [
                        "clx4b2m1e0003mp08w9f6tj5s"
                      ],
                      "type": "string"
                    },
                    "agentId": {
                      "description": "Id of the agent that owns the routine.",
                      "type": "string"
                    },
                    "applicationId": {
                      "description": "Id of the application the agent belongs to.",
                      "examples": [
                        42
                      ],
                      "type": "number"
                    },
                    "name": {
                      "description": "Display name of the routine.",
                      "type": "string"
                    },
                    "prompt": {
                      "description": "Prompt the agent executes on every run.",
                      "type": "string"
                    },
                    "enabled": {
                      "description": "Whether the routine is active.",
                      "type": "boolean"
                    },
                    "triggers": {
                      "description": "Triggers of the routine, including the implicit API trigger.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "Unique id of the trigger.",
                            "type": "string"
                          },
                          "type": {
                            "description": "Trigger type: `SCHEDULED`, `API`, or `DOCUMENT_EVENT`.",
                            "examples": [
                              "SCHEDULED"
                            ],
                            "type": "string"
                          },
                          "enabled": {
                            "description": "Whether the trigger is active.",
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "id",
                          "type",
                          "enabled"
                        ],
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "id",
                    "agentId",
                    "applicationId",
                    "name",
                    "prompt",
                    "enabled",
                    "triggers"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "Invalid body",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Routine not found or inaccessible",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteAgentRoutine",
        "summary": "Delete a routine of an agent",
        "tags": [
          "agent-routines"
        ],
        "description": "Permanently deletes the routine together with its triggers and removes the Cloud Scheduler jobs of its scheduled triggers.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "routineId",
            "in": "path",
            "required": true,
            "description": "Id of the routine.",
            "schema": {
              "examples": [
                "clx4b2m1e0003mp08w9f6tj5s"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application the routine belongs to. When omitted, it is derived from the routine (or, for the list route, from the agent); when given, the resource must belong to that application.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Routine deleted"
          },
          "400": {
            "description": "Invalid query parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Routine not found or inaccessible",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/routines/{routineId}/run/": {
      "post": {
        "operationId": "runAgentRoutine",
        "summary": "Queue an on-demand run of a routine",
        "tags": [
          "agent-routines"
        ],
        "description": "Requires `Authorization: ApiKey <key>` with the `FULL` or `ROUTINE` scope; session cookies are rejected. The routine must be enabled and have an enabled API trigger. Accepts an optional JSON body `{ text?: string }` (max 10k chars) that is passed to the routine as a prefix to the saved prompt. Answers `202` once the run is queued; the spawned thread and execution ids appear on the run row once the worker finishes.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "routineId",
            "in": "path",
            "required": true,
            "description": "Id of the routine.",
            "schema": {
              "examples": [
                "clx4b2m1e0003mp08w9f6tj5s"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Optional. Only parsed when the request carries a JSON content type. Bodies with other content types are ignored.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "text": {
                    "description": "Free text passed to the routine as a prefix to its saved prompt. At most 10000 characters.",
                    "examples": [
                      "Focus on the invoices received this week."
                    ],
                    "type": "string",
                    "maxLength": 10000
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "The run was queued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "description": "Always `routine_run`.",
                      "type": "string",
                      "const": "routine_run"
                    },
                    "runId": {
                      "description": "Id of the queued run. Fetch the routine with `GET /api/v1/agents/{agentId}/routines/{routineId}/` to follow its progress.",
                      "examples": [
                        "clx7e1q4h0009mp08u6j3wn8f"
                      ],
                      "type": "string"
                    },
                    "threadId": {
                      "description": "Always null at queue time. The spawned thread id appears on the run row once the worker finishes.",
                      "type": "null"
                    }
                  },
                  "required": [
                    "type",
                    "runId",
                    "threadId"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "403": {
            "description": "Wrong API key scope or no access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Routine not found for this agent",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "409": {
            "description": "Routine disabled or without an enabled API trigger",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/analytics/": {
      "get": {
        "operationId": "getAgentAnalytics",
        "summary": "Get all analytics sections of an agent (legacy)",
        "tags": [
          "agent-analytics"
        ],
        "description": "Deprecated legacy endpoint that returns every analytics section in one response. Prefer the per-section endpoints (summary, trends, durations, evaluations, unanswered).",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": true,
            "description": "Id of the application the agent belongs to.",
            "schema": {
              "examples": [
                "42"
              ],
              "type": "number"
            }
          },
          {
            "name": "dateRange",
            "in": "query",
            "required": false,
            "description": "Time window of the analytics: `7d`, `30d`, `90d`, `all`, or `custom`. Unknown values fall back to `30d`. Use `custom` together with `startDate` and `endDate`.",
            "schema": {
              "examples": [
                "30d"
              ]
            }
          },
          {
            "name": "executionType",
            "in": "query",
            "required": false,
            "description": "Filters executions by type: `all`, `LIVE`, or `EVAL`. Unknown values fall back to `all`.",
            "schema": {
              "examples": [
                "LIVE"
              ]
            }
          },
          {
            "name": "statuses",
            "in": "query",
            "required": false,
            "description": "Comma-separated execution statuses to include: `RUNNING`, `STOPPED`, `FINISHED`, `STALLED`, `TIMED_OUT`. Unknown entries are dropped. Empty means all statuses.",
            "schema": {
              "examples": [
                "FINISHED,STOPPED"
              ]
            }
          },
          {
            "name": "forceRefresh",
            "in": "query",
            "required": false,
            "description": "Pass `true` to bypass cached results. Only honored by the unanswered section.",
            "schema": {
              "examples": [
                "true"
              ]
            }
          },
          {
            "name": "startDate",
            "in": "query",
            "required": false,
            "description": "Start of a custom date window, an ISO 8601 date. Only takes effect when `endDate` is also given and both parse as dates in order.",
            "schema": {
              "examples": [
                "2026-06-01"
              ],
              "type": "string"
            }
          },
          {
            "name": "endDate",
            "in": "query",
            "required": false,
            "description": "End of a custom date window, an ISO 8601 date, inclusive to the end of the day. Ignored unless `startDate` is also valid and not after it.",
            "schema": {
              "examples": [
                "2026-06-30"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "All analytics sections for the agent in the requested window"
          },
          "400": {
            "description": "Invalid query parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/analytics/durations/": {
      "get": {
        "operationId": "getAgentAnalyticsDurations",
        "summary": "Get the durations analytics section of an agent",
        "tags": [
          "agent-analytics"
        ],
        "description": "Returns `executionDurations` (one point per execution), `nodeDurations` (one point per node) and `errorHotspotExecutions` (recent error executions, not limited to the scatter sample) for the requested window.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": true,
            "description": "Id of the application the agent belongs to.",
            "schema": {
              "examples": [
                "42"
              ],
              "type": "number"
            }
          },
          {
            "name": "dateRange",
            "in": "query",
            "required": false,
            "description": "Time window of the analytics: `7d`, `30d`, `90d`, `all`, or `custom`. Unknown values fall back to `30d`. Use `custom` together with `startDate` and `endDate`.",
            "schema": {
              "examples": [
                "30d"
              ]
            }
          },
          {
            "name": "executionType",
            "in": "query",
            "required": false,
            "description": "Filters executions by type: `all`, `LIVE`, or `EVAL`. Unknown values fall back to `all`.",
            "schema": {
              "examples": [
                "LIVE"
              ]
            }
          },
          {
            "name": "statuses",
            "in": "query",
            "required": false,
            "description": "Comma-separated execution statuses to include: `RUNNING`, `STOPPED`, `FINISHED`, `STALLED`, `TIMED_OUT`. Unknown entries are dropped. Empty means all statuses.",
            "schema": {
              "examples": [
                "FINISHED,STOPPED"
              ]
            }
          },
          {
            "name": "forceRefresh",
            "in": "query",
            "required": false,
            "description": "Pass `true` to bypass cached results. Only honored by the unanswered section.",
            "schema": {
              "examples": [
                "true"
              ]
            }
          },
          {
            "name": "startDate",
            "in": "query",
            "required": false,
            "description": "Start of a custom date window, an ISO 8601 date. Only takes effect when `endDate` is also given and both parse as dates in order.",
            "schema": {
              "examples": [
                "2026-06-01"
              ],
              "type": "string"
            }
          },
          {
            "name": "endDate",
            "in": "query",
            "required": false,
            "description": "End of a custom date window, an ISO 8601 date, inclusive to the end of the day. Ignored unless `startDate` is also valid and not after it.",
            "schema": {
              "examples": [
                "2026-06-30"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Individual execution durations and node durations for the window"
          },
          "400": {
            "description": "Invalid query parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/analytics/evaluations/": {
      "get": {
        "operationId": "getAgentAnalyticsEvaluations",
        "summary": "Get the evaluations analytics section of an agent",
        "tags": [
          "agent-analytics"
        ],
        "description": "Returns `evaluationDurations`, one point per individual evaluation with its score and duration, grouped by evaluation criteria, for the requested window.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": true,
            "description": "Id of the application the agent belongs to.",
            "schema": {
              "examples": [
                "42"
              ],
              "type": "number"
            }
          },
          {
            "name": "dateRange",
            "in": "query",
            "required": false,
            "description": "Time window of the analytics: `7d`, `30d`, `90d`, `all`, or `custom`. Unknown values fall back to `30d`. Use `custom` together with `startDate` and `endDate`.",
            "schema": {
              "examples": [
                "30d"
              ]
            }
          },
          {
            "name": "executionType",
            "in": "query",
            "required": false,
            "description": "Filters executions by type: `all`, `LIVE`, or `EVAL`. Unknown values fall back to `all`.",
            "schema": {
              "examples": [
                "LIVE"
              ]
            }
          },
          {
            "name": "statuses",
            "in": "query",
            "required": false,
            "description": "Comma-separated execution statuses to include: `RUNNING`, `STOPPED`, `FINISHED`, `STALLED`, `TIMED_OUT`. Unknown entries are dropped. Empty means all statuses.",
            "schema": {
              "examples": [
                "FINISHED,STOPPED"
              ]
            }
          },
          {
            "name": "forceRefresh",
            "in": "query",
            "required": false,
            "description": "Pass `true` to bypass cached results. Only honored by the unanswered section.",
            "schema": {
              "examples": [
                "true"
              ]
            }
          },
          {
            "name": "startDate",
            "in": "query",
            "required": false,
            "description": "Start of a custom date window, an ISO 8601 date. Only takes effect when `endDate` is also given and both parse as dates in order.",
            "schema": {
              "examples": [
                "2026-06-01"
              ],
              "type": "string"
            }
          },
          {
            "name": "endDate",
            "in": "query",
            "required": false,
            "description": "End of a custom date window, an ISO 8601 date, inclusive to the end of the day. Ignored unless `startDate` is also valid and not after it.",
            "schema": {
              "examples": [
                "2026-06-30"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Evaluation scores and durations grouped by criteria for the window"
          },
          "400": {
            "description": "Invalid query parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/analytics/execution-snapshots/": {
      "get": {
        "operationId": "getAgentAnalyticsExecutionSnapshots",
        "summary": "Get insight snapshots per execution of an agent",
        "tags": [
          "agent-analytics"
        ],
        "description": "Returns a map keyed by execution id with the latest conversation insights snapshot produced by each execution in the requested window.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": true,
            "description": "Id of the application the agent belongs to.",
            "schema": {
              "examples": [
                "42"
              ],
              "type": "number"
            }
          },
          {
            "name": "dateRange",
            "in": "query",
            "required": false,
            "description": "Time window of the analytics: `7d`, `30d`, `90d`, `all`, or `custom`. Unknown values fall back to `30d`. Use `custom` together with `startDate` and `endDate`.",
            "schema": {
              "examples": [
                "30d"
              ]
            }
          },
          {
            "name": "executionType",
            "in": "query",
            "required": false,
            "description": "Filters executions by type: `all`, `LIVE`, or `EVAL`. Unknown values fall back to `all`.",
            "schema": {
              "examples": [
                "LIVE"
              ]
            }
          },
          {
            "name": "statuses",
            "in": "query",
            "required": false,
            "description": "Comma-separated execution statuses to include: `RUNNING`, `STOPPED`, `FINISHED`, `STALLED`, `TIMED_OUT`. Unknown entries are dropped. Empty means all statuses.",
            "schema": {
              "examples": [
                "FINISHED,STOPPED"
              ]
            }
          },
          {
            "name": "forceRefresh",
            "in": "query",
            "required": false,
            "description": "Pass `true` to bypass cached results. Only honored by the unanswered section.",
            "schema": {
              "examples": [
                "true"
              ]
            }
          },
          {
            "name": "startDate",
            "in": "query",
            "required": false,
            "description": "Start of a custom date window, an ISO 8601 date. Only takes effect when `endDate` is also given and both parse as dates in order.",
            "schema": {
              "examples": [
                "2026-06-01"
              ],
              "type": "string"
            }
          },
          {
            "name": "endDate",
            "in": "query",
            "required": false,
            "description": "End of a custom date window, an ISO 8601 date, inclusive to the end of the day. Ignored unless `startDate` is also valid and not after it.",
            "schema": {
              "examples": [
                "2026-06-30"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Map of execution id to its insights snapshot (empty object when none)"
          },
          "400": {
            "description": "Invalid query parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/analytics/insights/": {
      "get": {
        "operationId": "getAgentAnalyticsInsights",
        "summary": "Get the conversation insights analytics section of an agent",
        "tags": [
          "agent-analytics"
        ],
        "description": "Returns `null` when the agent has Insights disabled or no data points configured; otherwise an object with `analyzedSnapshotCount` and one aggregate per configured data point.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": true,
            "description": "Id of the application the agent belongs to.",
            "schema": {
              "examples": [
                "42"
              ],
              "type": "number"
            }
          },
          {
            "name": "dateRange",
            "in": "query",
            "required": false,
            "description": "Time window of the analytics: `7d`, `30d`, `90d`, `all`, or `custom`. Unknown values fall back to `30d`. Use `custom` together with `startDate` and `endDate`.",
            "schema": {
              "examples": [
                "30d"
              ]
            }
          },
          {
            "name": "executionType",
            "in": "query",
            "required": false,
            "description": "Filters executions by type: `all`, `LIVE`, or `EVAL`. Unknown values fall back to `all`.",
            "schema": {
              "examples": [
                "LIVE"
              ]
            }
          },
          {
            "name": "statuses",
            "in": "query",
            "required": false,
            "description": "Comma-separated execution statuses to include: `RUNNING`, `STOPPED`, `FINISHED`, `STALLED`, `TIMED_OUT`. Unknown entries are dropped. Empty means all statuses.",
            "schema": {
              "examples": [
                "FINISHED,STOPPED"
              ]
            }
          },
          {
            "name": "forceRefresh",
            "in": "query",
            "required": false,
            "description": "Pass `true` to bypass cached results. Only honored by the unanswered section.",
            "schema": {
              "examples": [
                "true"
              ]
            }
          },
          {
            "name": "startDate",
            "in": "query",
            "required": false,
            "description": "Start of a custom date window, an ISO 8601 date. Only takes effect when `endDate` is also given and both parse as dates in order.",
            "schema": {
              "examples": [
                "2026-06-01"
              ],
              "type": "string"
            }
          },
          {
            "name": "endDate",
            "in": "query",
            "required": false,
            "description": "End of a custom date window, an ISO 8601 date, inclusive to the end of the day. Ignored unless `startDate` is also valid and not after it.",
            "schema": {
              "examples": [
                "2026-06-30"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Conversation insights aggregates, or null when the section is disabled"
          },
          "400": {
            "description": "Invalid query parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/analytics/summary/": {
      "get": {
        "operationId": "getAgentAnalyticsSummary",
        "summary": "Get the summary analytics section of an agent",
        "tags": [
          "agent-analytics"
        ],
        "description": "Returns `summary` (execution KPIs for the window), `statusDistribution` and `executionTypeDistribution`. Filters follow the shared analytics query semantics.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": true,
            "description": "Id of the application the agent belongs to.",
            "schema": {
              "examples": [
                "42"
              ],
              "type": "number"
            }
          },
          {
            "name": "dateRange",
            "in": "query",
            "required": false,
            "description": "Time window of the analytics: `7d`, `30d`, `90d`, `all`, or `custom`. Unknown values fall back to `30d`. Use `custom` together with `startDate` and `endDate`.",
            "schema": {
              "examples": [
                "30d"
              ]
            }
          },
          {
            "name": "executionType",
            "in": "query",
            "required": false,
            "description": "Filters executions by type: `all`, `LIVE`, or `EVAL`. Unknown values fall back to `all`.",
            "schema": {
              "examples": [
                "LIVE"
              ]
            }
          },
          {
            "name": "statuses",
            "in": "query",
            "required": false,
            "description": "Comma-separated execution statuses to include: `RUNNING`, `STOPPED`, `FINISHED`, `STALLED`, `TIMED_OUT`. Unknown entries are dropped. Empty means all statuses.",
            "schema": {
              "examples": [
                "FINISHED,STOPPED"
              ]
            }
          },
          {
            "name": "forceRefresh",
            "in": "query",
            "required": false,
            "description": "Pass `true` to bypass cached results. Only honored by the unanswered section.",
            "schema": {
              "examples": [
                "true"
              ]
            }
          },
          {
            "name": "startDate",
            "in": "query",
            "required": false,
            "description": "Start of a custom date window, an ISO 8601 date. Only takes effect when `endDate` is also given and both parse as dates in order.",
            "schema": {
              "examples": [
                "2026-06-01"
              ],
              "type": "string"
            }
          },
          {
            "name": "endDate",
            "in": "query",
            "required": false,
            "description": "End of a custom date window, an ISO 8601 date, inclusive to the end of the day. Ignored unless `startDate` is also valid and not after it.",
            "schema": {
              "examples": [
                "2026-06-30"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Execution KPIs plus status and execution-type distributions"
          },
          "400": {
            "description": "Invalid query parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/analytics/trends/": {
      "get": {
        "operationId": "getAgentAnalyticsTrends",
        "summary": "Get the trends analytics section of an agent",
        "tags": [
          "agent-analytics"
        ],
        "description": "Returns `dailyExecutions` (execution counts per day) and `dailyDuration` (duration percentiles per day) for the requested window.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": true,
            "description": "Id of the application the agent belongs to.",
            "schema": {
              "examples": [
                "42"
              ],
              "type": "number"
            }
          },
          {
            "name": "dateRange",
            "in": "query",
            "required": false,
            "description": "Time window of the analytics: `7d`, `30d`, `90d`, `all`, or `custom`. Unknown values fall back to `30d`. Use `custom` together with `startDate` and `endDate`.",
            "schema": {
              "examples": [
                "30d"
              ]
            }
          },
          {
            "name": "executionType",
            "in": "query",
            "required": false,
            "description": "Filters executions by type: `all`, `LIVE`, or `EVAL`. Unknown values fall back to `all`.",
            "schema": {
              "examples": [
                "LIVE"
              ]
            }
          },
          {
            "name": "statuses",
            "in": "query",
            "required": false,
            "description": "Comma-separated execution statuses to include: `RUNNING`, `STOPPED`, `FINISHED`, `STALLED`, `TIMED_OUT`. Unknown entries are dropped. Empty means all statuses.",
            "schema": {
              "examples": [
                "FINISHED,STOPPED"
              ]
            }
          },
          {
            "name": "forceRefresh",
            "in": "query",
            "required": false,
            "description": "Pass `true` to bypass cached results. Only honored by the unanswered section.",
            "schema": {
              "examples": [
                "true"
              ]
            }
          },
          {
            "name": "startDate",
            "in": "query",
            "required": false,
            "description": "Start of a custom date window, an ISO 8601 date. Only takes effect when `endDate` is also given and both parse as dates in order.",
            "schema": {
              "examples": [
                "2026-06-01"
              ],
              "type": "string"
            }
          },
          {
            "name": "endDate",
            "in": "query",
            "required": false,
            "description": "End of a custom date window, an ISO 8601 date, inclusive to the end of the day. Ignored unless `startDate` is also valid and not after it.",
            "schema": {
              "examples": [
                "2026-06-30"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Daily execution counts and duration percentiles for the window"
          },
          "400": {
            "description": "Invalid query parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/analytics/unanswered/": {
      "get": {
        "operationId": "getAgentAnalyticsUnanswered",
        "summary": "Get the unanswered-threads analytics section of an agent",
        "tags": [
          "agent-analytics"
        ],
        "description": "Pass `forceRefresh=true` to bypass the cached getters and recompute the section.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": true,
            "description": "Id of the application the agent belongs to.",
            "schema": {
              "examples": [
                "42"
              ],
              "type": "number"
            }
          },
          {
            "name": "dateRange",
            "in": "query",
            "required": false,
            "description": "Time window of the analytics: `7d`, `30d`, `90d`, `all`, or `custom`. Unknown values fall back to `30d`. Use `custom` together with `startDate` and `endDate`.",
            "schema": {
              "examples": [
                "30d"
              ]
            }
          },
          {
            "name": "executionType",
            "in": "query",
            "required": false,
            "description": "Filters executions by type: `all`, `LIVE`, or `EVAL`. Unknown values fall back to `all`.",
            "schema": {
              "examples": [
                "LIVE"
              ]
            }
          },
          {
            "name": "statuses",
            "in": "query",
            "required": false,
            "description": "Comma-separated execution statuses to include: `RUNNING`, `STOPPED`, `FINISHED`, `STALLED`, `TIMED_OUT`. Unknown entries are dropped. Empty means all statuses.",
            "schema": {
              "examples": [
                "FINISHED,STOPPED"
              ]
            }
          },
          {
            "name": "forceRefresh",
            "in": "query",
            "required": false,
            "description": "Pass `true` to bypass cached results. Only honored by the unanswered section.",
            "schema": {
              "examples": [
                "true"
              ]
            }
          },
          {
            "name": "startDate",
            "in": "query",
            "required": false,
            "description": "Start of a custom date window, an ISO 8601 date. Only takes effect when `endDate` is also given and both parse as dates in order.",
            "schema": {
              "examples": [
                "2026-06-01"
              ],
              "type": "string"
            }
          },
          {
            "name": "endDate",
            "in": "query",
            "required": false,
            "description": "End of a custom date window, an ISO 8601 date, inclusive to the end of the day. Ignored unless `startDate` is also valid and not after it.",
            "schema": {
              "examples": [
                "2026-06-30"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Daily unanswered thread counts and currently unanswered threads"
          },
          "400": {
            "description": "Invalid query parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/auto-improve/": {
      "post": {
        "operationId": "startAgentAutoImprove",
        "summary": "Start the auto-improve process for an agent",
        "tags": [
          "agent-improvement"
        ],
        "description": "Runs the selected evals (or all of the agent when `testCaseIds` is omitted), analyzes results and iteratively improves the agent flow until `targetScore` is reached or `maxIterations` runs are done. When a process is already running, answers 200 with its id instead of starting another one.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "targetScore": {
                    "description": "Average eval score, from 0 to 10, at which the process stops improving.",
                    "examples": [
                      8
                    ],
                    "type": "number"
                  },
                  "maxIterations": {
                    "description": "Maximum number of improvement iterations, an integer from 1 to 10.",
                    "examples": [
                      5
                    ],
                    "type": "number"
                  },
                  "applicationId": {
                    "description": "Positive integer id of the application that scopes this operation.",
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  "testCaseIds": {
                    "description": "Ids of the agent evals to run on each iteration. Every id must belong to the agent. Omit to run all of the agent test cases.",
                    "examples": [
                      [
                        "clx8f3r5j000bmp08v8k5xp3g"
                      ]
                    ]
                  }
                },
                "required": [
                  "targetScore",
                  "maxIterations"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The started (or already running) process",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the process was started or was already running.",
                      "type": "boolean"
                    },
                    "processId": {
                      "description": "Id of the auto-improve run. Use it with `GET /api/v1/agents/{agentId}/auto-improve/runs/{runId}/` and `DELETE /api/v1/agents/{agentId}/auto-improve/stop/`.",
                      "examples": [
                        "clx5c7n2f0005mp08r2g8uk1d"
                      ],
                      "type": "string"
                    },
                    "message": {
                      "description": "Present when a process was already running for the agent.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "success",
                    "processId"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or unusable eval selection",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No write access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/auto-improve/runs/": {
      "get": {
        "operationId": "listAgentAutoImproveRuns",
        "summary": "List auto-improve runs of an agent",
        "tags": [
          "agent-improvement"
        ],
        "description": "Returns the runs newest first, at most `limit` of them (default 20). When `applicationId` is given, read access to the application is checked first.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application the agent belongs to. When given, read access to it is checked.",
            "schema": {
              "examples": [
                42
              ],
              "type": "number"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of runs to return. Defaults to 20.",
            "schema": {
              "examples": [
                20
              ],
              "default": 20,
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The auto-improve runs, newest first",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "description": "Unique id of the run.",
                        "type": "string"
                      },
                      "agentId": {
                        "description": "Id of the agent the run improves.",
                        "type": "string"
                      },
                      "status": {
                        "description": "Status of the run: `RUNNING`, `COMPLETED`, `ERROR`, or `STOPPED`.",
                        "examples": [
                          "COMPLETED"
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "id",
                      "agentId",
                      "status"
                    ],
                    "additionalProperties": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No read access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/auto-improve/runs/{runId}/": {
      "get": {
        "operationId": "getAgentAutoImproveRun",
        "summary": "Get an auto-improve run of an agent",
        "tags": [
          "agent-improvement"
        ],
        "description": "Returns the run together with the test runs of its iterations. Use it to poll the progress of a process started via `POST /api/v1/agents/{agentId}/auto-improve/`. Answers `400` when the run exists but belongs to a different agent.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "description": "Id of the auto-improve run.",
            "schema": {
              "examples": [
                "clx5c7n2f0005mp08r2g8uk1d"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application the agent belongs to. When given, read access to it is checked.",
            "schema": {
              "examples": [
                42
              ],
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The auto-improve run with its test runs",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "Unique id of the run.",
                      "type": "string"
                    },
                    "agentId": {
                      "description": "Id of the agent the run improves.",
                      "type": "string"
                    },
                    "status": {
                      "description": "Status of the run: `RUNNING`, `COMPLETED`, `ERROR`, or `STOPPED`.",
                      "examples": [
                        "COMPLETED"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "agentId",
                    "status"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "Run does not belong to the agent",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No read access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Run not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteAgentAutoImproveRun",
        "summary": "Delete an auto-improve run of an agent",
        "tags": [
          "agent-improvement"
        ],
        "description": "Permanently removes the run record. It does not stop a running process, use `POST /api/v1/agents/{agentId}/auto-improve/stop/` for that. When `applicationId` is given, write access to it is checked.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "description": "Id of the auto-improve run.",
            "schema": {
              "examples": [
                "clx5c7n2f0005mp08r2g8uk1d"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application the agent belongs to. When given, write access to it is checked.",
            "schema": {
              "examples": [
                42
              ],
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The run was deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the action succeeded.",
                      "type": "boolean"
                    },
                    "message": {
                      "description": "Human-readable outcome of the action.",
                      "examples": [
                        "Process stopped successfully"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "success",
                    "message"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameters or run/agent mismatch",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No write access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Run not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/auto-improve/stop/": {
      "post": {
        "operationId": "stopAgentAutoImproveRun",
        "summary": "Stop a running auto-improve process of an agent",
        "tags": [
          "agent-improvement"
        ],
        "description": "Marks the run identified by `processId` as `STOPPED` so the background process terminates gracefully at its next checkpoint instead of starting another iteration. Answers `404` when the process has already finished or been stopped. When `applicationId` is given, write access to it is checked.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "processId",
            "in": "query",
            "required": true,
            "description": "Id of the auto-improve run to stop, as returned by `POST /api/v1/agents/{agentId}/auto-improve/`.",
            "schema": {
              "examples": [
                "clx5c7n2f0005mp08r2g8uk1d"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application the agent belongs to. When given, write access to it is checked.",
            "schema": {
              "examples": [
                42
              ],
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The process was stopped",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the action succeeded.",
                      "type": "boolean"
                    },
                    "message": {
                      "description": "Human-readable outcome of the action.",
                      "examples": [
                        "Process stopped successfully"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "success",
                    "message"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameters or run/agent mismatch",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No write access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Run not found or already stopped",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "stopAgentAutoImprove",
        "summary": "Stop a running auto-improve process of an agent (deprecated method)",
        "tags": [
          "agent-improvement"
        ],
        "description": "Deprecated spelling of `POST /api/v1/agents/{agentId}/auto-improve/stop/`: stopping is an action, not a resource deletion, so POST is the canonical method. Behaves identically.",
        "deprecated": true,
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "processId",
            "in": "query",
            "required": true,
            "description": "Id of the auto-improve run to stop, as returned by `POST /api/v1/agents/{agentId}/auto-improve/`.",
            "schema": {
              "examples": [
                "clx5c7n2f0005mp08r2g8uk1d"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application the agent belongs to. When given, write access to it is checked.",
            "schema": {
              "examples": [
                42
              ],
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The process was stopped",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the action succeeded.",
                      "type": "boolean"
                    },
                    "message": {
                      "description": "Human-readable outcome of the action.",
                      "examples": [
                        "Process stopped successfully"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "success",
                    "message"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameters or run/agent mismatch",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No write access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Run not found or already stopped",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/threads/": {
      "get": {
        "operationId": "listAgentThreads",
        "summary": "List sandbox threads of an agent",
        "tags": [
          "agents"
        ],
        "description": "Without `threadGroupId` the agent sandbox group (`agent-sandbox:{agentId}`) is listed with type AGENT_SANDBOX. Passing `threadGroupId` lists that group instead, optionally narrowed by `type`. `q` filters threads by the display text of their first user message.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "take",
            "in": "query",
            "required": false,
            "description": "Maximum number of threads to return. Non-numeric or non-positive values fall back to the default: 100 when `q` is given, 10 otherwise.",
            "schema": {
              "examples": [
                "25"
              ]
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Search text matched against the display text of each thread first user message. Case-insensitive contains match.",
            "schema": {}
          },
          {
            "name": "threadGroupId",
            "in": "query",
            "required": false,
            "description": "Thread group to list. Defaults to the agent sandbox group `agent-sandbox:{agentId}`.",
            "schema": {
              "examples": [
                "agent-sandbox:clx3f8a9d0001mp08q7d3vhk2"
              ]
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Thread type filter, for example `AGENT_SANDBOX` or `WHATSAPP`. Only applied when `threadGroupId` is given. Unknown values are ignored.",
            "schema": {
              "examples": [
                "AGENT_SANDBOX"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The matching threads, most recently updated first",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "threads": {
                      "description": "The matching threads, most recently updated first.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "Unique id of the thread.",
                            "type": "string"
                          },
                          "archived": {
                            "description": "Whether the thread is archived.",
                            "type": "boolean"
                          },
                          "description": {
                            "description": "Description of the thread, or null when it has none.",
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "updatedAt": {
                            "description": "When the thread was last updated, an ISO 8601 timestamp.",
                            "examples": [
                              "2026-07-01T12:34:56.000Z"
                            ],
                            "type": "string"
                          },
                          "messages": {
                            "description": "The first user message of the thread, or empty when the thread has none.",
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "description": "Unique id of the message.",
                                  "type": "string"
                                }
                              },
                              "required": [
                                "id"
                              ],
                              "additionalProperties": {}
                            }
                          }
                        },
                        "required": [
                          "id",
                          "archived",
                          "description",
                          "updatedAt",
                          "messages"
                        ],
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "threads"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the agent application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/threads/{threadId}/messages/": {
      "get": {
        "operationId": "listAgentThreadMessages",
        "summary": "List messages of an agent thread",
        "tags": [
          "agents"
        ],
        "description": "Looks the thread up by id within the agent application, so any agent thread works — sandbox, builder, and live execution threads (type AGENT, as returned by getAgentExecution) alike. `threadGroupId` and `type` are optional narrowing filters; a mismatch returns 404.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "threadId",
            "in": "path",
            "required": true,
            "description": "Id of the thread.",
            "schema": {
              "examples": [
                "clx6d9p3g0007mp08t4h1vm2e"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "threadGroupId",
            "in": "query",
            "required": false,
            "description": "Optional narrowing filter: only match the thread when it belongs to this group. Omit it to look the thread up by id alone — required for live execution threads, whose group is a random cuid.",
            "schema": {
              "examples": [
                "agent-sandbox:clx3f8a9d0001mp08q7d3vhk2"
              ]
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Optional thread type narrowing filter, for example `AGENT` or `AGENT_SANDBOX`. Unknown values are ignored.",
            "schema": {
              "examples": [
                "AGENT"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "All messages of the thread, oldest first",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "messages": {
                      "description": "All messages of the thread, oldest first.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "Id of the message.",
                            "type": "string"
                          },
                          "role": {
                            "description": "Author role of the message: `USER`, `ASSISTANT`, `SYSTEM`, or `TOOL`.",
                            "examples": [
                              "USER"
                            ],
                            "type": "string"
                          },
                          "content": {
                            "description": "Content of the message: a string, or an array of parts. Attachment file parts carry the `documentId` of the ingested attachment, a `url` pointing at `GET /api/v1/documents/{documentId}/download/` (authenticated), and a `viewUrl` — a time-limited pre-authorized link to the same bytes that can be fetched, rendered or attached without platform credentials (it expires after a few hours; re-fetch the message for a fresh one). Document URLs embedded in tool results (for example a search result’s `downloadUrl`) carry the same time-limited `vid` token and are directly fetchable too. The transcription or extracted text of that attachment is available at `GET /api/v1/documents/{documentId}/content/`."
                          }
                        },
                        "required": [
                          "id",
                          "role",
                          "content"
                        ],
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "messages"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the agent application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Thread not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/follow-ups/{followUpId}/cancel/": {
      "post": {
        "operationId": "cancelAgentFollowUp",
        "summary": "Cancel a scheduled follow-up of an agent",
        "tags": [
          "agents"
        ],
        "description": "Deletes the follow-up scheduler job so it never fires and marks the source execution node as cancelled. Idempotent: cancelling a follow-up whose job is already gone still succeeds. The `applicationId` query parameter is optional: when omitted, it is derived from the follow-up itself. To trigger the follow-up instead, use `POST /api/v1/agents/{agentId}/follow-ups/{followUpId}/fire-now/`.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "followUpId",
            "in": "path",
            "required": true,
            "description": "Id of the scheduled follow-up.",
            "schema": {
              "examples": [
                "fu_8f2c1b7a4d"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application the follow-up thread belongs to. When omitted, it is derived from the follow-up itself; when given, the follow-up must belong to that application.",
            "schema": {
              "examples": [
                42
              ],
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The follow-up was cancelled",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the follow-up action succeeded.",
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "success"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Follow-up not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/follow-ups/{followUpId}/fire-now/": {
      "post": {
        "operationId": "fireAgentFollowUpNow",
        "summary": "Fire a scheduled follow-up of an agent immediately",
        "tags": [
          "agents"
        ],
        "description": "Runs the follow-up scheduler job now instead of waiting for its scheduled time. The schedule itself is not modified, but the later scheduled tick is absorbed by the worker because the manual run has already produced an assistant message. The `applicationId` query parameter is optional: when omitted, it is derived from the follow-up itself. To stop the follow-up instead, use `POST /api/v1/agents/{agentId}/follow-ups/{followUpId}/cancel/`.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "followUpId",
            "in": "path",
            "required": true,
            "description": "Id of the scheduled follow-up.",
            "schema": {
              "examples": [
                "fu_8f2c1b7a4d"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application the follow-up thread belongs to. When omitted, it is derived from the follow-up itself; when given, the follow-up must belong to that application.",
            "schema": {
              "examples": [
                42
              ],
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The follow-up was triggered",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the follow-up action succeeded.",
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "success"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Follow-up not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agents/{agentId}/insights/": {
      "get": {
        "operationId": "pollAgentInsights",
        "summary": "Poll the latest document insights results of an agent",
        "tags": [
          "agent-analytics"
        ],
        "description": "Returns the latest evaluation results with completion percentage and pagination metadata. `sort` and `dir` follow the insights table sort params; `q` filters rows.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "Id of the agent.",
            "schema": {
              "examples": [
                "clx3f8a9d0001mp08q7d3vhk2"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of result rows per page. Defaults to 50.",
            "schema": {
              "examples": [
                "50"
              ],
              "type": "string"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Number of rows to skip before the page. Defaults to 0.",
            "schema": {
              "examples": [
                "0"
              ],
              "type": "string"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Field to sort by: `source` for the source column, or `{criteriaId}:score` / `{criteriaId}:value` for an insight column.",
            "schema": {
              "examples": [
                "source"
              ],
              "type": "string"
            }
          },
          {
            "name": "dir",
            "in": "query",
            "required": false,
            "description": "Sort direction, `asc` or `desc`. Defaults to `asc`.",
            "schema": {
              "examples": [
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Filter text matched against each row source name and cell values. Case-insensitive contains match.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The latest insight results page with completion metadata",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "latestResults": {
                      "description": "Latest evaluation results for the requested page of threads."
                    },
                    "metadata": {
                      "description": "Per-result metadata keyed by evaluation result id, including agent reasoning when available."
                    },
                    "completionPercentage": {
                      "description": "Share of expected evaluation results already produced, from 0 to 100."
                    },
                    "insightDocument": {
                      "description": "The latest insight document generated for the agent, or null when none exists."
                    }
                  },
                  "required": [
                    "latestResults",
                    "metadata",
                    "completionPercentage",
                    "insightDocument"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/applications/": {
      "get": {
        "operationId": "listApplications",
        "summary": "List applications",
        "tags": [
          "applications"
        ],
        "description": "Returns only applications the caller can access through ownership, direct membership, or team membership. Non-admin callers always get `ACTIVE` applications, admins can request `ARCHIVED` via `status`. All filters combine with AND. Pass `responseShape=summary` for a lean, cursor-paginated envelope (stable identity fields only) instead of the default full array; use `limit` and `cursor` to page through it.",
        "parameters": [
          {
            "name": "group",
            "in": "query",
            "required": false,
            "description": "Filter by application group. Matches an `ApplicationGroup` enum value such as `LEGAL` or `FINANCE`.",
            "schema": {
              "examples": [
                "LEGAL"
              ],
              "type": "string"
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Case-insensitive substring match on the application name and description.",
            "schema": {
              "examples": [
                "contract"
              ],
              "type": "string"
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Filter by application type, for example `ASSISTANT`.",
            "schema": {
              "examples": [
                "ASSISTANT"
              ],
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by lifecycle status. Only admins can request `ARCHIVED`, other callers always get `ACTIVE`.",
            "schema": {
              "examples": [
                "ACTIVE"
              ],
              "type": "string",
              "enum": [
                "ACTIVE",
                "ARCHIVED"
              ]
            }
          },
          {
            "name": "responseShape",
            "in": "query",
            "required": false,
            "description": "Opt into the lean, cursor-paginated summary envelope `{ applications, nextCursor }` instead of the default full array. Returns only stable identity fields (`id`, `name`, `companyId`, `userId`, `type`, `group`, `status`, `createdAt`, `updatedAt`) — no memberships, collections, or agent graph. Intended for token-sensitive clients (MCP, CLI). The default response shape is unchanged when this is omitted.",
            "schema": {
              "examples": [
                "summary"
              ],
              "type": "string",
              "const": "summary"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size when `responseShape=summary`, bounded between 1 and 100. Defaults to 50. Ignored for the default (full) response shape.",
            "schema": {
              "examples": [
                50
              ],
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Opaque pagination cursor returned as `nextCursor` by a previous `responseShape=summary` request. Order is stable: `createdAt` desc, then `id` desc.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Applications visible to the caller. Default: a flat array of full application objects. With `responseShape=summary`: `{ applications, nextCursor }` lean envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "The application's unique id.",
                            "examples": [
                              42
                            ],
                            "type": "number"
                          },
                          "name": {
                            "description": "The application name.",
                            "examples": [
                              "Contract Review Assistant"
                            ],
                            "type": "string"
                          },
                          "companyId": {
                            "description": "Id of the company that owns the application.",
                            "examples": [
                              7
                            ],
                            "type": "number"
                          },
                          "userId": {
                            "description": "Id of the user who created the application.",
                            "examples": [
                              15
                            ],
                            "type": "number"
                          },
                          "type": {
                            "description": "The application type, for example `ASSISTANT`.",
                            "examples": [
                              "ASSISTANT"
                            ],
                            "type": "string"
                          },
                          "group": {
                            "description": "The industry group the application is organized under, for example `DEFAULT`.",
                            "examples": [
                              "DEFAULT"
                            ],
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "companyId",
                          "userId",
                          "type",
                          "group"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    {
                      "type": "object",
                      "properties": {
                        "applications": {
                          "description": "One page of lean application summaries, most recently created first.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "description": "The application's unique id.",
                                "examples": [
                                  42
                                ],
                                "type": "number"
                              },
                              "name": {
                                "description": "The application name.",
                                "examples": [
                                  "Contract Review Assistant"
                                ],
                                "type": "string"
                              },
                              "companyId": {
                                "description": "Id of the company that owns the application.",
                                "examples": [
                                  7
                                ],
                                "type": "number"
                              },
                              "userId": {
                                "description": "Id of the user who created the application.",
                                "examples": [
                                  15
                                ],
                                "type": "number"
                              },
                              "type": {
                                "description": "The application type, for example `ASSISTANT`.",
                                "examples": [
                                  "ASSISTANT"
                                ],
                                "type": "string"
                              },
                              "group": {
                                "description": "The industry group the application is organized under, for example `DEFAULT`.",
                                "examples": [
                                  "DEFAULT"
                                ],
                                "type": "string"
                              },
                              "status": {
                                "description": "The application lifecycle status, for example `ACTIVE`.",
                                "examples": [
                                  "ACTIVE"
                                ],
                                "type": "string"
                              },
                              "createdAt": {
                                "description": "ISO-8601 timestamp of when the application was created.",
                                "examples": [
                                  "2025-01-31T12:00:00.000Z"
                                ],
                                "type": "string"
                              },
                              "updatedAt": {
                                "description": "ISO-8601 timestamp of the most recent update to the application.",
                                "examples": [
                                  "2025-02-04T08:30:00.000Z"
                                ],
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "name",
                              "companyId",
                              "userId",
                              "type",
                              "group",
                              "status",
                              "createdAt",
                              "updatedAt"
                            ],
                            "additionalProperties": false
                          }
                        },
                        "nextCursor": {
                          "description": "Opaque cursor to pass back as `cursor` for the next page. `null` once the final page has been reached.",
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "applications",
                        "nextCursor"
                      ],
                      "additionalProperties": false
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createApplication",
        "summary": "Create an application",
        "tags": [
          "applications"
        ],
        "description": "Creates the application owned by the caller and adds the caller as an active `ADMIN` member. Requires company-level permission to write applications.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "description": "The application name shown across the platform.",
                    "examples": [
                      "Contract Review Assistant"
                    ],
                    "type": "string",
                    "minLength": 1
                  },
                  "description": {
                    "description": "Optional free-text description. Also matched by the `search` filter when listing applications.",
                    "type": "string"
                  },
                  "type": {
                    "description": "The kind of application to create. Defaults to `ASSISTANT`.",
                    "examples": [
                      "ASSISTANT"
                    ],
                    "default": "ASSISTANT",
                    "type": "string",
                    "enum": [
                      "ASSISTANT",
                      "QUESTION_ANSWERING",
                      "DOCUMENT_INSIGHTS",
                      "SEARCH",
                      "RECOMMENDATION"
                    ]
                  },
                  "group": {
                    "description": "Industry group used to organize applications. Defaults to `DEFAULT`.",
                    "examples": [
                      "LEGAL"
                    ],
                    "default": "DEFAULT",
                    "type": "string",
                    "enum": [
                      "ADVISORY",
                      "ASSET_MANAGEMENT",
                      "CONSTRUCTION",
                      "CONSULTING",
                      "CORPORATE",
                      "CREDIT",
                      "DEFAULT",
                      "FINANCE",
                      "INSURANCE",
                      "LEGAL",
                      "REAL_ESTATE",
                      "RETAIL"
                    ]
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "The application's unique id.",
                      "examples": [
                        42
                      ],
                      "type": "number"
                    },
                    "name": {
                      "description": "The application name.",
                      "examples": [
                        "Contract Review Assistant"
                      ],
                      "type": "string"
                    },
                    "companyId": {
                      "description": "Id of the company that owns the application.",
                      "examples": [
                        7
                      ],
                      "type": "number"
                    },
                    "userId": {
                      "description": "Id of the user who created the application.",
                      "examples": [
                        15
                      ],
                      "type": "number"
                    },
                    "type": {
                      "description": "The application type, for example `ASSISTANT`.",
                      "examples": [
                        "ASSISTANT"
                      ],
                      "type": "string"
                    },
                    "group": {
                      "description": "The industry group the application is organized under, for example `DEFAULT`.",
                      "examples": [
                        "DEFAULT"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "name",
                    "companyId",
                    "userId",
                    "type",
                    "group"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No permission to create applications",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/applications/{id}/": {
      "get": {
        "operationId": "getApplication",
        "summary": "Get an application",
        "tags": [
          "applications"
        ],
        "description": "Returns one application in the same item shape as the `GET /api/applications/` list.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "The application's unique id.",
                      "examples": [
                        42
                      ],
                      "type": "number"
                    },
                    "name": {
                      "description": "The application name.",
                      "examples": [
                        "Contract Review Assistant"
                      ],
                      "type": "string"
                    },
                    "companyId": {
                      "description": "Id of the company that owns the application.",
                      "examples": [
                        7
                      ],
                      "type": "number"
                    },
                    "userId": {
                      "description": "Id of the user who created the application.",
                      "examples": [
                        15
                      ],
                      "type": "number"
                    },
                    "type": {
                      "description": "The application type, for example `ASSISTANT`.",
                      "examples": [
                        "ASSISTANT"
                      ],
                      "type": "string"
                    },
                    "group": {
                      "description": "The industry group the application is organized under, for example `DEFAULT`.",
                      "examples": [
                        "DEFAULT"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "name",
                    "companyId",
                    "userId",
                    "type",
                    "group"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Application not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateApplication",
        "summary": "Update an application",
        "tags": [
          "applications"
        ],
        "description": "Updates one or more of the application name, description, and group. Omitted fields are preserved. Requires write access.",
        "x-docana-mcp-tool": true,
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "description": "New application name. Renames the application-owned collection too.",
                    "examples": [
                      "Contract Review Assistant"
                    ],
                    "type": "string",
                    "minLength": 1
                  },
                  "description": {
                    "description": "New free-text application description. Omit to preserve the existing description.",
                    "examples": [
                      "Reviews contracts before they are signed."
                    ],
                    "type": "string"
                  },
                  "group": {
                    "description": "New industry group used to organize the application.",
                    "examples": [
                      "LEGAL"
                    ],
                    "type": "string",
                    "enum": [
                      "ADVISORY",
                      "ASSET_MANAGEMENT",
                      "CONSTRUCTION",
                      "CONSULTING",
                      "CORPORATE",
                      "CREDIT",
                      "DEFAULT",
                      "FINANCE",
                      "INSURANCE",
                      "LEGAL",
                      "REAL_ESTATE",
                      "RETAIL"
                    ]
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "The application's unique id.",
                      "examples": [
                        42
                      ],
                      "type": "number"
                    },
                    "name": {
                      "description": "The application name.",
                      "examples": [
                        "Contract Review Assistant"
                      ],
                      "type": "string"
                    },
                    "companyId": {
                      "description": "Id of the company that owns the application.",
                      "examples": [
                        7
                      ],
                      "type": "number"
                    },
                    "userId": {
                      "description": "Id of the user who created the application.",
                      "examples": [
                        15
                      ],
                      "type": "number"
                    },
                    "type": {
                      "description": "The application type, for example `ASSISTANT`.",
                      "examples": [
                        "ASSISTANT"
                      ],
                      "type": "string"
                    },
                    "group": {
                      "description": "The industry group the application is organized under, for example `DEFAULT`.",
                      "examples": [
                        "DEFAULT"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "name",
                    "companyId",
                    "userId",
                    "type",
                    "group"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No write access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/applications/{id}/collections/{collectionId}/": {
      "put": {
        "operationId": "linkApplicationCollection",
        "summary": "Link a collection to an application",
        "tags": [
          "applications"
        ],
        "description": "Grants the application access to the collection, so its agents can search and read the documents inside. The caller needs write access to the application and access to the collection.",
        "x-docana-mcp-tool": true,
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "collectionId",
            "in": "path",
            "required": true,
            "description": "The collection id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The collection is linked to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "applicationId": {
                      "description": "Id of the application.",
                      "examples": [
                        42
                      ],
                      "type": "number"
                    },
                    "collectionId": {
                      "description": "Id of the collection.",
                      "examples": [
                        99
                      ],
                      "type": "number"
                    },
                    "linked": {
                      "description": "Whether the collection is linked after this request.",
                      "examples": [
                        true
                      ],
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "success",
                    "applicationId",
                    "collectionId",
                    "linked"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The collection cannot be linked",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No application write or collection access",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "unlinkApplicationCollection",
        "summary": "Unlink a collection from an application",
        "tags": [
          "applications"
        ],
        "description": "Removes the application's access to the collection. The collection and its documents stay untouched. A collection owned by the application itself cannot be unlinked.",
        "x-docana-mcp-tool": true,
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "collectionId",
            "in": "path",
            "required": true,
            "description": "The collection id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The collection is unlinked from the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "applicationId": {
                      "description": "Id of the application.",
                      "examples": [
                        42
                      ],
                      "type": "number"
                    },
                    "collectionId": {
                      "description": "Id of the collection.",
                      "examples": [
                        99
                      ],
                      "type": "number"
                    },
                    "linked": {
                      "description": "Whether the collection is linked after this request.",
                      "examples": [
                        true
                      ],
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "success",
                    "applicationId",
                    "collectionId",
                    "linked"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The application-owned collection cannot be unlinked",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No application write or collection access",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/applications/{id}/skills/": {
      "get": {
        "operationId": "listApplicationSkills",
        "summary": "List selectable application skills",
        "tags": [
          "applications"
        ],
        "description": "Lists the skills the company allows, each with its selection state for this application.",
        "x-docana-mcp-tool": true,
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Company-allowed skills and application selection state",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "skills": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "scope": {
                            "type": "string",
                            "const": "COMPANY"
                          },
                          "source": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "enabled": {
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "description",
                          "scope",
                          "source",
                          "enabled"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "success",
                    "skills"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No read access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/applications/{id}/skills/{skillId}/": {
      "put": {
        "operationId": "selectApplicationSkill",
        "summary": "Select a skill for an application",
        "tags": [
          "applications"
        ],
        "description": "Makes the skill available to the application's agents.",
        "x-docana-mcp-tool": true,
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "skillId",
            "in": "path",
            "required": true,
            "description": "The company skill id.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The selected skill",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "skill": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "description": {
                          "type": "string"
                        },
                        "scope": {
                          "type": "string",
                          "const": "COMPANY"
                        },
                        "source": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "enabled": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "description",
                        "scope",
                        "source",
                        "enabled"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "skill"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No write access or skill access",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deselectApplicationSkill",
        "summary": "Deselect a skill for an application",
        "tags": [
          "applications"
        ],
        "description": "Removes the skill from the application's agents.",
        "x-docana-mcp-tool": true,
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "skillId",
            "in": "path",
            "required": true,
            "description": "The company skill id.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The deselected skill",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "skill": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "description": {
                          "type": "string"
                        },
                        "scope": {
                          "type": "string",
                          "const": "COMPANY"
                        },
                        "source": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "enabled": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "description",
                        "scope",
                        "source",
                        "enabled"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "skill"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No write access or skill access",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/applications/{id}/mcp-servers/": {
      "get": {
        "operationId": "listApplicationMcpServers",
        "summary": "List MCP servers selectable by an application",
        "tags": [
          "applications"
        ],
        "description": "Lists the MCP server connections in the workspace, each with its selection state for this application.",
        "x-docana-mcp-tool": true,
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Safe MCP server selection details",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "mcpServers": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "description": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "transport": {
                            "type": "string",
                            "enum": [
                              "sse",
                              "http"
                            ]
                          },
                          "authMethod": {
                            "type": "string",
                            "enum": [
                              "none",
                              "oauth",
                              "bearer"
                            ]
                          },
                          "enabledForApplication": {
                            "type": "boolean"
                          },
                          "eligible": {
                            "type": "boolean"
                          },
                          "ineligibleReason": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "description",
                          "transport",
                          "authMethod",
                          "enabledForApplication",
                          "eligible",
                          "ineligibleReason"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "mcpServers"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No read access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/applications/{id}/mcp-servers/{mcpServerId}/": {
      "put": {
        "operationId": "enableApplicationMcpServer",
        "summary": "Enable an MCP server for an application",
        "tags": [
          "applications"
        ],
        "description": "Lets the application's agents call the MCP server's tools.",
        "x-docana-mcp-tool": true,
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "mcpServerId",
            "in": "path",
            "required": true,
            "description": "The MCP server id (cuid).",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The server is enabled",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "enabledForApplication": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "success",
                    "enabledForApplication"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Server is not eligible",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "MCP server not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "disableApplicationMcpServer",
        "summary": "Disable an MCP server for an application",
        "tags": [
          "applications"
        ],
        "description": "Stops the application's agents from calling the MCP server's tools.",
        "x-docana-mcp-tool": true,
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "mcpServerId",
            "in": "path",
            "required": true,
            "description": "The MCP server id (cuid).",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The server is disabled",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "enabledForApplication": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "success",
                    "enabledForApplication"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/applications/{id}/environments/": {
      "get": {
        "operationId": "listApplicationEnvironments",
        "summary": "List environments of an application",
        "tags": [
          "applications"
        ],
        "description": "Environments are named sets of key-value variables that agents resolve through `{{env.*}}` placeholders at run time. Values are stored encrypted and returned decrypted here.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The application environments",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "description": "UUID of the environment.",
                        "examples": [
                          "b7f9d2a4-1c3e-4f6a-9b2d-8e5c7a1f4d30"
                        ],
                        "type": "string"
                      },
                      "name": {
                        "description": "The environment name.",
                        "examples": [
                          "Production"
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "id",
                      "name"
                    ],
                    "additionalProperties": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No read access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createApplicationEnvironment",
        "summary": "Create an application environment",
        "tags": [
          "applications"
        ],
        "description": "Environment names are unique per application, compared case-insensitively. Variables are encrypted before storage. Requires write access to the application.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "description": "The environment name. Unique per application, compared case-insensitively.",
                    "examples": [
                      "Production"
                    ],
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "variables": {
                    "description": "Key-value variables stored encrypted at rest. Agents resolve them through `{{env.*}}` placeholders at run time. Defaults to an empty map.",
                    "examples": [
                      {
                        "API_BASE_URL": "https://api.example.com"
                      }
                    ],
                    "default": {},
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {
                      "type": "string"
                    }
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created environment",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "UUID of the environment.",
                      "examples": [
                        "b7f9d2a4-1c3e-4f6a-9b2d-8e5c7a1f4d30"
                      ],
                      "type": "string"
                    },
                    "name": {
                      "description": "The environment name.",
                      "examples": [
                        "Production"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "name"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No write access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "updateApplicationEnvironment",
        "summary": "Update an application environment (deprecated shape)",
        "tags": [
          "applications"
        ],
        "description": "Deprecated: use `PUT /api/v1/applications/{id}/environments/{environmentId}/`, which addresses the environment in the path instead of the `environmentId` body field. This variant behaves identically. Provide `name`, `variables`, or both. A provided `variables` map replaces every existing variable.",
        "deprecated": true,
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "environmentId": {
                    "description": "UUID of the environment to update.",
                    "examples": [
                      "b7f9d2a4-1c3e-4f6a-9b2d-8e5c7a1f4d30"
                    ],
                    "type": "string",
                    "minLength": 1
                  },
                  "name": {
                    "description": "New environment name. Unique per application, compared case-insensitively.",
                    "examples": [
                      "Staging"
                    ],
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "variables": {
                    "description": "Replacement variable map. When provided it replaces every existing variable of the environment.",
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {
                      "type": "string"
                    }
                  }
                },
                "required": [
                  "environmentId"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated environment",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "UUID of the environment.",
                      "examples": [
                        "b7f9d2a4-1c3e-4f6a-9b2d-8e5c7a1f4d30"
                      ],
                      "type": "string"
                    },
                    "name": {
                      "description": "The environment name.",
                      "examples": [
                        "Production"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "name"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No write access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Environment not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteApplicationEnvironment",
        "summary": "Delete an application environment (deprecated shape)",
        "tags": [
          "applications"
        ],
        "description": "Deprecated: use `DELETE /api/v1/applications/{id}/environments/{environmentId}/`, which addresses the environment in the path instead of a required request body — a shape several HTTP clients cannot send. This variant behaves identically. Agents that still reference the deleted environment resolve their `{{env.*}}` placeholders to empty values.",
        "deprecated": true,
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "environmentId": {
                    "description": "UUID of the environment to delete.",
                    "examples": [
                      "b7f9d2a4-1c3e-4f6a-9b2d-8e5c7a1f4d30"
                    ],
                    "type": "string",
                    "minLength": 1
                  }
                },
                "required": [
                  "environmentId"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Deletion confirmation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "success"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No write access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Environment not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/applications/{id}/environments/{environmentId}/": {
      "put": {
        "operationId": "updateApplicationEnvironmentById",
        "summary": "Update an application environment",
        "tags": [
          "applications"
        ],
        "description": "Provide `name`, `variables`, or both. A provided `variables` map replaces every existing variable. Requires write access to the application.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "environmentId",
            "in": "path",
            "required": true,
            "description": "UUID of the environment.",
            "schema": {
              "examples": [
                "b7f9d2a4-1c3e-4f6a-9b2d-8e5c7a1f4d30"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "description": "New environment name. Unique per application, compared case-insensitively.",
                    "examples": [
                      "Staging"
                    ],
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "variables": {
                    "description": "Replacement variable map. When provided it replaces every existing variable of the environment.",
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated environment",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "UUID of the environment.",
                      "examples": [
                        "b7f9d2a4-1c3e-4f6a-9b2d-8e5c7a1f4d30"
                      ],
                      "type": "string"
                    },
                    "name": {
                      "description": "The environment name.",
                      "examples": [
                        "Production"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "name"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No write access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Environment not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteApplicationEnvironmentById",
        "summary": "Delete an application environment",
        "tags": [
          "applications"
        ],
        "description": "Agents that still reference the deleted environment resolve their `{{env.*}}` placeholders to empty values. Requires write access to the application.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "environmentId",
            "in": "path",
            "required": true,
            "description": "UUID of the environment.",
            "schema": {
              "examples": [
                "b7f9d2a4-1c3e-4f6a-9b2d-8e5c7a1f4d30"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deletion confirmation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "success"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No write access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Environment not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/applications/{id}/allowed-websites/": {
      "get": {
        "operationId": "listApplicationAllowedWebsites",
        "summary": "List allowed websites of an application",
        "tags": [
          "applications"
        ],
        "description": "Merges the company-level website records with the per-application link, so each row carries the global configuration plus an `enabledForApplication` toggle. Stored passwords are reported through `hasStoredPassword` and the ciphertext is never returned.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Allowed websites linked to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "allowedWebsites": {
                      "description": "Websites linked to the application, merging the company-level record with the per-application toggle.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "The allowed website id (cuid).",
                            "examples": [
                              "clx3k9f2m0001ab8xq4y7znlp"
                            ],
                            "type": "string"
                          },
                          "name": {
                            "description": "Display name of the allowed website.",
                            "examples": [
                              "Example Patient Portal"
                            ],
                            "type": "string"
                          },
                          "url": {
                            "description": "The allowed URL, or `*` for unrestricted entries.",
                            "examples": [
                              "https://portal.example.com/"
                            ],
                            "type": "string"
                          },
                          "hasStoredPassword": {
                            "description": "True when an encrypted password is stored for the site. The password itself is never returned.",
                            "type": "boolean"
                          },
                          "enabledForApplication": {
                            "description": "Whether the website is enabled for this specific application (the per-application toggle).",
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "url",
                          "hasStoredPassword",
                          "enabledForApplication"
                        ],
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "allowedWebsites"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No read access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createApplicationAllowedWebsite",
        "summary": "Create an allowed website for an application",
        "tags": [
          "applications"
        ],
        "description": "Creates a company-level allowed website and links it to the application in one call. A plain-text `password` is encrypted before storage. Use `PATCH /api/v1/applications/{id}/allowed-websites/{siteId}/` to toggle the per-application link later.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "description": "Display name for the allowed website entry.",
                    "examples": [
                      "Example Patient Portal"
                    ],
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "description": {
                    "description": "Optional note explaining what the site is used for.",
                    "examples": [
                      "Patient portal the intake agent reads lab results from."
                    ],
                    "type": "string",
                    "maxLength": 2000
                  },
                  "url": {
                    "description": "The URL the browser engine may visit. Must be a parseable URL for `WEBSITE` entries. `UNRESTRICTED` entries use `*`.",
                    "examples": [
                      "https://portal.example.com/"
                    ],
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2048
                  },
                  "type": {
                    "description": "`WEBSITE` allows one specific URL. `UNRESTRICTED` (`*`) allows any URL. Defaults to `WEBSITE`.",
                    "examples": [
                      "WEBSITE"
                    ],
                    "type": "string",
                    "enum": [
                      "WEBSITE",
                      "UNRESTRICTED"
                    ]
                  },
                  "webEngine": {
                    "description": "`BASIC` uses a fast read-only fetcher for public pages. `ADVANCED` uses a remote headless browser that supports logins and JavaScript-heavy pages. Defaults to `BASIC`.",
                    "examples": [
                      "ADVANCED"
                    ],
                    "type": "string",
                    "enum": [
                      "BASIC",
                      "ADVANCED"
                    ]
                  },
                  "country": {
                    "description": "2-letter lowercase ISO country code used as the proxy egress location for ADVANCED browser sessions. Helps with geo-fenced sites.",
                    "examples": [
                      "us"
                    ],
                    "type": "string",
                    "pattern": "^[a-z]{2}$"
                  },
                  "username": {
                    "description": "Login username the browser agent types into the site. Only used by ADVANCED entries.",
                    "examples": [
                      "reports@example.com"
                    ],
                    "type": "string",
                    "maxLength": 255
                  },
                  "password": {
                    "description": "Plain-text login password. Encrypted server-side before storage and never returned by the API.",
                    "examples": [
                      "correct-horse-battery-staple"
                    ],
                    "type": "string",
                    "maxLength": 1024
                  },
                  "persistContext": {
                    "description": "When true, ADVANCED browser sessions reuse a persistent browser profile (cookies and auth tokens) across runs, so a login done on one run survives to the next. Ignored for BASIC entries. Defaults to false.",
                    "examples": [
                      true
                    ],
                    "type": "boolean"
                  },
                  "enabled": {
                    "description": "Whether the entry is enabled at the company level. Defaults to true.",
                    "examples": [
                      true
                    ],
                    "type": "boolean"
                  },
                  "isPrivate": {
                    "description": "When true the entry is visible only to its creator. Defaults to true.",
                    "examples": [
                      true
                    ],
                    "type": "boolean"
                  }
                },
                "required": [
                  "name",
                  "url"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created allowed website (without ciphertext)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "allowedWebsite": {
                      "description": "The allowed website record without credential ciphertext.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "The allowed website id (cuid).",
                          "examples": [
                            "clx3k9f2m0001ab8xq4y7znlp"
                          ],
                          "type": "string"
                        },
                        "name": {
                          "description": "Display name of the allowed website.",
                          "examples": [
                            "Example Patient Portal"
                          ],
                          "type": "string"
                        },
                        "url": {
                          "description": "The allowed URL, or `*` for unrestricted entries.",
                          "examples": [
                            "https://portal.example.com/"
                          ],
                          "type": "string"
                        },
                        "hasStoredPassword": {
                          "description": "True when an encrypted password is stored for the site. The password itself is never returned.",
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "url",
                        "hasStoredPassword"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "allowedWebsite"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No write access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/applications/{id}/allowed-websites/{siteId}/": {
      "get": {
        "operationId": "getApplicationAllowedWebsite",
        "summary": "Get one allowed website of an application",
        "tags": [
          "applications"
        ],
        "description": "The response replaces stored credentials with a `hasStoredPassword` boolean. The password ciphertext is never returned.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "siteId",
            "in": "path",
            "required": true,
            "description": "The allowed website id (cuid).",
            "schema": {
              "examples": [
                "clx3k9f2m0001ab8xq4y7znlp"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The allowed website (without ciphertext)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "allowedWebsite": {
                      "description": "The allowed website record without credential ciphertext.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "The allowed website id (cuid).",
                          "examples": [
                            "clx3k9f2m0001ab8xq4y7znlp"
                          ],
                          "type": "string"
                        },
                        "name": {
                          "description": "Display name of the allowed website.",
                          "examples": [
                            "Example Patient Portal"
                          ],
                          "type": "string"
                        },
                        "url": {
                          "description": "The allowed URL, or `*` for unrestricted entries.",
                          "examples": [
                            "https://portal.example.com/"
                          ],
                          "type": "string"
                        },
                        "hasStoredPassword": {
                          "description": "True when an encrypted password is stored for the site. The password itself is never returned.",
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "url",
                        "hasStoredPassword"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "allowedWebsite"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No read access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Allowed website not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateApplicationAllowedWebsite",
        "summary": "Update an allowed website of an application",
        "tags": [
          "applications"
        ],
        "description": "Most fields update the company-level record shared by every application, while `enabledForApplication` toggles only the link to this application. `password: null` clears the stored credentials, omitting the field keeps them.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "siteId",
            "in": "path",
            "required": true,
            "description": "The allowed website id (cuid).",
            "schema": {
              "examples": [
                "clx3k9f2m0001ab8xq4y7znlp"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "description": "New display name for the entry.",
                    "examples": [
                      "Example Patient Portal"
                    ],
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "description": {
                    "description": "New note explaining what the site is used for.",
                    "examples": [
                      "Patient portal the intake agent reads lab results from."
                    ],
                    "type": "string",
                    "maxLength": 2000
                  },
                  "url": {
                    "description": "New URL. Must be a parseable URL for `WEBSITE` entries. `UNRESTRICTED` entries use `*`.",
                    "examples": [
                      "https://portal.example.com/"
                    ],
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2048
                  },
                  "type": {
                    "description": "`WEBSITE` allows one specific URL. `UNRESTRICTED` (`*`) allows any URL.",
                    "examples": [
                      "WEBSITE"
                    ],
                    "type": "string",
                    "enum": [
                      "WEBSITE",
                      "UNRESTRICTED"
                    ]
                  },
                  "webEngine": {
                    "description": "`BASIC` uses a fast read-only fetcher for public pages. `ADVANCED` uses a remote headless browser that supports logins and JavaScript-heavy pages.",
                    "examples": [
                      "ADVANCED"
                    ],
                    "type": "string",
                    "enum": [
                      "BASIC",
                      "ADVANCED"
                    ]
                  },
                  "country": {
                    "description": "2-letter lowercase ISO country code used as the proxy egress location for ADVANCED browser sessions. Pass `null` to clear it.",
                    "examples": [
                      "us"
                    ],
                    "anyOf": [
                      {
                        "type": "string",
                        "pattern": "^[a-z]{2}$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "username": {
                    "description": "Login username for ADVANCED entries. Pass `null` to clear it.",
                    "examples": [
                      "reports@example.com"
                    ],
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 255
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "password": {
                    "description": "Plain-text login password, encrypted server-side. Pass `null` to clear the stored credentials. Omit the field to keep the existing ones.",
                    "examples": [
                      "correct-horse-battery-staple"
                    ],
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 1024
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "persistContext": {
                    "description": "When true, ADVANCED browser sessions reuse a persistent browser profile (cookies and auth tokens) across runs. Ignored for BASIC entries.",
                    "examples": [
                      true
                    ],
                    "type": "boolean"
                  },
                  "enabled": {
                    "description": "Whether the entry is enabled at the company level.",
                    "examples": [
                      true
                    ],
                    "type": "boolean"
                  },
                  "isPrivate": {
                    "description": "When true the entry is visible only to its creator.",
                    "examples": [
                      true
                    ],
                    "type": "boolean"
                  },
                  "enabledForApplication": {
                    "description": "When provided, toggles the per-application link for this website without changing the company-level record.",
                    "examples": [
                      true
                    ],
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated allowed website (without ciphertext)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "allowedWebsite": {
                      "description": "The allowed website record without credential ciphertext.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "The allowed website id (cuid).",
                          "examples": [
                            "clx3k9f2m0001ab8xq4y7znlp"
                          ],
                          "type": "string"
                        },
                        "name": {
                          "description": "Display name of the allowed website.",
                          "examples": [
                            "Example Patient Portal"
                          ],
                          "type": "string"
                        },
                        "url": {
                          "description": "The allowed URL, or `*` for unrestricted entries.",
                          "examples": [
                            "https://portal.example.com/"
                          ],
                          "type": "string"
                        },
                        "hasStoredPassword": {
                          "description": "True when an encrypted password is stored for the site. The password itself is never returned.",
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "url",
                        "hasStoredPassword"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "allowedWebsite"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Update or link-toggle failure",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No write access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteApplicationAllowedWebsite",
        "summary": "Delete an allowed website",
        "tags": [
          "applications"
        ],
        "description": "Deletes the company-level record, which removes the website from every application it is linked to, not just the one in the path.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "siteId",
            "in": "path",
            "required": true,
            "description": "The allowed website id (cuid).",
            "schema": {
              "examples": [
                "clx3k9f2m0001ab8xq4y7znlp"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deletion confirmation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "success"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Deletion failure",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No write access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/applications/{id}/threads/": {
      "get": {
        "operationId": "listApplicationThreads",
        "summary": "List threads of an application",
        "tags": [
          "applications"
        ],
        "description": "`limit` is clamped to 100. `threadGroupId` switches to a compact playground-history shape. `format=preview` strips full message content down to a display preview.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search over thread id, description, agent name, and message author. Combine with `searchContent=true` to also match message content.",
            "schema": {
              "examples": [
                "invoice"
              ],
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Search text used in thread-group mode. Falls back to `search` when omitted.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "searchContent",
            "in": "query",
            "required": false,
            "description": "Pass the literal string `true` to extend the search into message content and thread metadata. Slower than the default search.",
            "schema": {
              "examples": [
                "true"
              ],
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "description": "Pass `preview` to strip full message content down to a compact display preview per thread.",
            "schema": {
              "examples": [
                "preview"
              ],
              "type": "string"
            }
          },
          {
            "name": "threadGroupId",
            "in": "query",
            "required": false,
            "description": "Scopes the list to one playground thread group and switches the response to a compact history shape.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "take",
            "in": "query",
            "required": false,
            "description": "Maximum number of threads returned in thread-group mode, capped at 100. Defaults to 10, or 100 when a search is present. Ignored outside thread-group mode.",
            "schema": {
              "examples": [
                "25"
              ],
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-based page number. Values below 1 are clamped to 1. Defaults to 1.",
            "schema": {
              "examples": [
                1
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size, clamped between 1 and 100. Defaults to 50.",
            "schema": {
              "examples": [
                50
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "One page of threads",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "threads": {
                      "description": "One page of unpinned threads, most recently updated first.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "The thread id.",
                            "examples": [
                              "0d5f9b1c-7a2e-4c8d-b6f3-2a9e4c7d1b50"
                            ],
                            "type": "string"
                          }
                        },
                        "required": [
                          "id"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "pinnedThreads": {
                      "description": "Pinned threads for the assistant sidebar (most recently pinned first). Capped at 50.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "The pinned thread id.",
                            "examples": [
                              "0d5f9b1c-7a2e-4c8d-b6f3-2a9e4c7d1b50"
                            ],
                            "type": "string"
                          }
                        },
                        "required": [
                          "id"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "hasNextPage": {
                      "description": "True when more pages exist after this one.",
                      "type": "boolean"
                    },
                    "totalCount": {
                      "description": "Exact number of matching unpinned threads. Only returned for the default list view. Search results use a cheaper has-next-page probe instead.",
                      "type": "number"
                    }
                  },
                  "required": [
                    "threads"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No read access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Application not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/applications/{id}/browser-context/reset/": {
      "post": {
        "operationId": "resetApplicationBrowserContext",
        "summary": "Reset the persistent browser context of an application",
        "tags": [
          "applications"
        ],
        "description": "Discards the stored persistent browser context id, the shared browser profile that carries cookies and auth tokens across `ADVANCED` browser runs, so the next run mints a fresh context and logs in from scratch. Use it when cookies persisted by a failed or expired login break subsequent logins. Idempotent, requires write access to the application.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Reset confirmation (idempotent)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "reset": {
                      "description": "Always true. The reset is idempotent whether or not a context id was stored.",
                      "type": "boolean"
                    },
                    "applicationId": {
                      "description": "Id of the application whose browser context was cleared.",
                      "examples": [
                        42
                      ],
                      "type": "number"
                    }
                  },
                  "required": [
                    "reset",
                    "applicationId"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No write access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/applications/{id}/mcp-oauth-status/": {
      "get": {
        "operationId": "getApplicationMcpOAuthStatus",
        "summary": "List pending MCP OAuth connections of an application",
        "tags": [
          "applications"
        ],
        "description": "Checks the OAuth MCP servers enabled on the application and returns the ones that block the assistant for the calling user, that is servers with a `not_connected` or `expired` connection. Each entry carries a `settingsPath` pointing to the page where the connection can be completed. Connected and expiring-soon servers are excluded.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OAuth MCP servers the user still needs to connect",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "pendingConnections": {
                      "description": "OAuth MCP servers enabled on the application that block the assistant until the user connects.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "mcpServerId": {
                            "description": "Id of the MCP server (cuid).",
                            "examples": [
                              "clx3k9f2m0001ab8xq4y7znlp"
                            ],
                            "type": "string"
                          },
                          "mcpServerName": {
                            "description": "Display name of the MCP server.",
                            "examples": [
                              "Salesforce"
                            ],
                            "type": "string"
                          },
                          "status": {
                            "description": "The OAuth connection status. Only blocking statuses appear in this list, either `not_connected` or `expired`.",
                            "examples": [
                              "not_connected"
                            ],
                            "type": "string"
                          },
                          "settingsPath": {
                            "description": "Relative platform path where the user can complete the OAuth connection.",
                            "examples": [
                              "/developer/mcp-servers/edit/clx3k9f2m0001ab8xq4y7znlp/"
                            ],
                            "type": "string"
                          }
                        },
                        "required": [
                          "mcpServerId",
                          "mcpServerName",
                          "status",
                          "settingsPath"
                        ],
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "pendingConnections"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Failed to load MCP OAuth status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/applications/{id}/recommendations/": {
      "get": {
        "operationId": "listApplicationRecommendations",
        "summary": "List recommendations of an application",
        "tags": [
          "applications"
        ],
        "description": "Returns the recommendation configurations of the application plus pagination metadata (`total`, `page`, `limit`, `totalPages`). Defaults to page 1 with 10 items, sorted by `createdAt` descending.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-based page number.",
            "schema": {
              "examples": [
                1
              ],
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size, at most 100.",
            "schema": {
              "examples": [
                20
              ],
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Field the results are sorted by.",
            "schema": {
              "examples": [
                "updatedAt"
              ],
              "type": "string",
              "enum": [
                "createdAt",
                "updatedAt",
                "lastRunAt"
              ]
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "required": false,
            "description": "Sort direction.",
            "schema": {
              "examples": [
                "desc"
              ],
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Recommendations of the application, paginated"
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createApplicationRecommendation",
        "summary": "Create a recommendation for an application",
        "tags": [
          "applications"
        ],
        "description": "Registers a recommendation that finds documents similar to the seed `inputs`. A scheduler job recalculates it on `updateFrequencyCron`, hourly by default. Use `POST /api/v1/applications/{id}/recommendations/{recommendationId}/trigger/` to run it immediately.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "description": "Display name of the recommendation.",
                    "examples": [
                      "Related market reports"
                    ],
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "inputs": {
                    "description": "Seed documents the engine finds similar content for.",
                    "minItems": 1,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "description": "The input kind. Only `document` is supported.",
                          "type": "string",
                          "const": "document"
                        },
                        "documentId": {
                          "description": "Id of the seed document the recommendation is computed from.",
                          "examples": [
                            1234
                          ],
                          "type": "integer",
                          "exclusiveMinimum": 0,
                          "maximum": 9007199254740991
                        }
                      },
                      "required": [
                        "type",
                        "documentId"
                      ]
                    }
                  },
                  "refinement": {
                    "description": "Optional free-text query. It is embedded and used as an extra similarity signal to steer the results.",
                    "examples": [
                      "quarterly earnings outlook"
                    ],
                    "type": "string"
                  },
                  "updateFrequencyCron": {
                    "description": "Cron expression controlling scheduled recalculation. Defaults to `0 * * * *` (hourly).",
                    "examples": [
                      "0 * * * *"
                    ],
                    "type": "string"
                  },
                  "config": {
                    "description": "Tuning options for the recommendation engine. Omitted fields fall back to the engine defaults.",
                    "type": "object",
                    "properties": {
                      "maxSimilarChunksPerDocument": {
                        "description": "Number of similar chunks fetched per input document during vector search. Defaults to 100.",
                        "examples": [
                          100
                        ],
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 100
                      },
                      "maxChunksPerInputDocument": {
                        "description": "How many chunks of each input document are searched. Long documents are sampled evenly rather than truncated. Defaults to 25.",
                        "examples": [
                          25
                        ],
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 200
                      },
                      "maxTotalSearchesPerRun": {
                        "description": "Ceiling on vector searches issued by one recommendation run. Inputs beyond the budget are skipped and the run logs a warning. Defaults to 500.",
                        "examples": [
                          500
                        ],
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 5000
                      },
                      "maxRecommendedDocuments": {
                        "description": "Maximum number of recommended documents returned. Defaults to 20.",
                        "examples": [
                          20
                        ],
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 100
                      },
                      "minSimilarityScore": {
                        "description": "Minimum aggregated similarity score, from 0 to 1, a document needs to be included in the results. Defaults to 0.7.",
                        "examples": [
                          0.7
                        ],
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1
                      },
                      "aggregationMethod": {
                        "description": "How per-chunk similarity scores are combined into one document score. Defaults to `average`.",
                        "examples": [
                          "average"
                        ],
                        "type": "string",
                        "enum": [
                          "average",
                          "max",
                          "sum"
                        ]
                      },
                      "resultsGrouping": {
                        "description": "`byDocument` returns a flat list of documents. `byCollection` groups the results per collection. Defaults to `byDocument`.",
                        "examples": [
                          "byDocument"
                        ],
                        "type": "string",
                        "enum": [
                          "byDocument",
                          "byCollection"
                        ]
                      }
                    }
                  },
                  "status": {
                    "description": "Lifecycle status. `PAUSED` recommendations skip scheduled runs.",
                    "examples": [
                      "SCHEDULED"
                    ],
                    "type": "string",
                    "enum": [
                      "SCHEDULED",
                      "RUNNING",
                      "PAUSED",
                      "ARCHIVED"
                    ]
                  }
                },
                "required": [
                  "name",
                  "inputs"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created recommendation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "The recommendation's numeric id.",
                      "examples": [
                        118
                      ],
                      "type": "number"
                    },
                    "applicationId": {
                      "description": "Id of the application the recommendation belongs to.",
                      "examples": [
                        42
                      ],
                      "type": "number"
                    },
                    "name": {
                      "description": "Display name of the recommendation.",
                      "examples": [
                        "Related market reports"
                      ],
                      "type": "string"
                    },
                    "inputs": {
                      "description": "Seed document inputs, including `visitedAt` and `visitCount` tracking fields when present.",
                      "type": "array",
                      "items": {}
                    },
                    "results": {
                      "description": "Computed recommendation results, grouped by document or by collection depending on `config.resultsGrouping`."
                    }
                  },
                  "required": [
                    "id",
                    "applicationId",
                    "name",
                    "inputs",
                    "results"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "Validation failure",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/applications/{id}/recommendations/{recommendationId}/": {
      "get": {
        "operationId": "getApplicationRecommendation",
        "summary": "Get a recommendation with enriched results",
        "tags": [
          "applications"
        ],
        "description": "`recommendationId` accepts the numeric id or the UUID. The stored results are enriched with document metadata, or collection metadata when grouped by collection, before being returned.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "recommendationId",
            "in": "path",
            "required": true,
            "description": "The recommendation id, either the numeric id or the UUID.",
            "schema": {
              "examples": [
                "118"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The recommendation with enriched results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "The recommendation's numeric id.",
                      "examples": [
                        118
                      ],
                      "type": "number"
                    },
                    "applicationId": {
                      "description": "Id of the application the recommendation belongs to.",
                      "examples": [
                        42
                      ],
                      "type": "number"
                    },
                    "name": {
                      "description": "Display name of the recommendation.",
                      "examples": [
                        "Related market reports"
                      ],
                      "type": "string"
                    },
                    "inputs": {
                      "description": "Seed document inputs, including `visitedAt` and `visitCount` tracking fields when present.",
                      "type": "array",
                      "items": {}
                    },
                    "results": {
                      "description": "Computed recommendation results, grouped by document or by collection depending on `config.resultsGrouping`."
                    }
                  },
                  "required": [
                    "id",
                    "applicationId",
                    "name",
                    "inputs",
                    "results"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Recommendation not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "updateApplicationRecommendation",
        "summary": "Update a recommendation",
        "tags": [
          "applications"
        ],
        "description": "`recommendationId` accepts the numeric id or the UUID. A provided `inputs` array replaces every existing input, and updating `updateFrequencyCron` reschedules the background job.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "recommendationId",
            "in": "path",
            "required": true,
            "description": "The recommendation id, either the numeric id or the UUID.",
            "schema": {
              "examples": [
                "118"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "description": "New display name of the recommendation.",
                    "examples": [
                      "Related market reports"
                    ],
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "inputs": {
                    "description": "Replacement list of seed documents. When provided it replaces every existing input.",
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "description": "The input kind. Only `document` is supported.",
                          "type": "string",
                          "const": "document"
                        },
                        "documentId": {
                          "description": "Id of the seed document the recommendation is computed from.",
                          "examples": [
                            1234
                          ],
                          "type": "integer",
                          "exclusiveMinimum": 0,
                          "maximum": 9007199254740991
                        }
                      },
                      "required": [
                        "type",
                        "documentId"
                      ]
                    }
                  },
                  "refinement": {
                    "description": "Optional free-text query. It is embedded and used as an extra similarity signal to steer the results.",
                    "examples": [
                      "quarterly earnings outlook"
                    ],
                    "type": "string"
                  },
                  "updateFrequencyCron": {
                    "description": "Cron expression controlling scheduled recalculation. Updating it reschedules the background job.",
                    "examples": [
                      "0 * * * *"
                    ],
                    "type": "string"
                  },
                  "config": {
                    "description": "Tuning options for the recommendation engine. Omitted fields fall back to the engine defaults.",
                    "type": "object",
                    "properties": {
                      "maxSimilarChunksPerDocument": {
                        "description": "Number of similar chunks fetched per input document during vector search. Defaults to 100.",
                        "examples": [
                          100
                        ],
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 100
                      },
                      "maxChunksPerInputDocument": {
                        "description": "How many chunks of each input document are searched. Long documents are sampled evenly rather than truncated. Defaults to 25.",
                        "examples": [
                          25
                        ],
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 200
                      },
                      "maxTotalSearchesPerRun": {
                        "description": "Ceiling on vector searches issued by one recommendation run. Inputs beyond the budget are skipped and the run logs a warning. Defaults to 500.",
                        "examples": [
                          500
                        ],
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 5000
                      },
                      "maxRecommendedDocuments": {
                        "description": "Maximum number of recommended documents returned. Defaults to 20.",
                        "examples": [
                          20
                        ],
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 100
                      },
                      "minSimilarityScore": {
                        "description": "Minimum aggregated similarity score, from 0 to 1, a document needs to be included in the results. Defaults to 0.7.",
                        "examples": [
                          0.7
                        ],
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1
                      },
                      "aggregationMethod": {
                        "description": "How per-chunk similarity scores are combined into one document score. Defaults to `average`.",
                        "examples": [
                          "average"
                        ],
                        "type": "string",
                        "enum": [
                          "average",
                          "max",
                          "sum"
                        ]
                      },
                      "resultsGrouping": {
                        "description": "`byDocument` returns a flat list of documents. `byCollection` groups the results per collection. Defaults to `byDocument`.",
                        "examples": [
                          "byDocument"
                        ],
                        "type": "string",
                        "enum": [
                          "byDocument",
                          "byCollection"
                        ]
                      }
                    }
                  },
                  "status": {
                    "description": "Lifecycle status. `PAUSED` recommendations skip scheduled runs.",
                    "examples": [
                      "PAUSED"
                    ],
                    "type": "string",
                    "enum": [
                      "SCHEDULED",
                      "RUNNING",
                      "PAUSED",
                      "ARCHIVED"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated recommendation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "The recommendation's numeric id.",
                      "examples": [
                        118
                      ],
                      "type": "number"
                    },
                    "applicationId": {
                      "description": "Id of the application the recommendation belongs to.",
                      "examples": [
                        42
                      ],
                      "type": "number"
                    },
                    "name": {
                      "description": "Display name of the recommendation.",
                      "examples": [
                        "Related market reports"
                      ],
                      "type": "string"
                    },
                    "inputs": {
                      "description": "Seed document inputs, including `visitedAt` and `visitCount` tracking fields when present.",
                      "type": "array",
                      "items": {}
                    },
                    "results": {
                      "description": "Computed recommendation results, grouped by document or by collection depending on `config.resultsGrouping`."
                    }
                  },
                  "required": [
                    "id",
                    "applicationId",
                    "name",
                    "inputs",
                    "results"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Recommendation not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteApplicationRecommendation",
        "summary": "Delete a recommendation",
        "tags": [
          "applications"
        ],
        "description": "`recommendationId` accepts the numeric id or the UUID. Deleting also removes the scheduler job that recalculates the recommendation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "recommendationId",
            "in": "path",
            "required": true,
            "description": "The recommendation id, either the numeric id or the UUID.",
            "schema": {
              "examples": [
                "118"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deletion confirmation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "message"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Recommendation not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/applications/{id}/recommendations/{recommendationId}/trigger/": {
      "post": {
        "operationId": "triggerApplicationRecommendation",
        "summary": "Trigger a recommendation calculation",
        "tags": [
          "applications"
        ],
        "description": "`mode=sync` calculates and returns enriched results immediately; `mode=async` (default) queues it.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "recommendationId",
            "in": "path",
            "required": true,
            "description": "The recommendation id, either the numeric id or the UUID.",
            "schema": {
              "examples": [
                "118"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "mode",
            "in": "query",
            "required": false,
            "description": "`sync` calculates the recommendation in the request and returns the results. `async` enqueues a background calculation. Defaults to `async`.",
            "schema": {
              "examples": [
                "async"
              ],
              "default": "async",
              "type": "string",
              "enum": [
                "sync",
                "async"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Trigger confirmation; sync mode also carries the enriched results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    },
                    "recommendationId": {
                      "type": "number"
                    },
                    "results": {}
                  },
                  "required": [
                    "message",
                    "recommendationId"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Recommendation not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/applications/{id}/recommendations/{recommendationId}/documents/{documentId}/": {
      "put": {
        "operationId": "upsertApplicationRecommendationDocument",
        "summary": "Record a document visit on a recommendation",
        "tags": [
          "applications"
        ],
        "description": "Stamps `visitedAt` and increments `visitCount` on the matching document input, or appends a new input with `visitCount: 1` when the document is not among the inputs yet. Requires access to both the application and the document.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "recommendationId",
            "in": "path",
            "required": true,
            "description": "The numeric recommendation id. UUIDs are not accepted here.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "documentId",
            "in": "path",
            "required": true,
            "description": "The document id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The document input was updated or added",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "success",
                    "message"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application or document",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Recommendation not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "removeApplicationRecommendationDocument",
        "summary": "Remove a document from a recommendation",
        "tags": [
          "applications"
        ],
        "description": "Removes the matching document input from the recommendation. Returns 404 when the document is not among the inputs.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The application id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "recommendationId",
            "in": "path",
            "required": true,
            "description": "The numeric recommendation id. UUIDs are not accepted here.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "documentId",
            "in": "path",
            "required": true,
            "description": "The document id.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The document was removed from the inputs",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "success",
                    "message"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Recommendation or document input not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/artifacts/": {
      "get": {
        "operationId": "listArtifactVersions",
        "summary": "List versions of an artifact",
        "tags": [
          "artifacts"
        ],
        "description": "Returns one page of up to 50 versions, newest first. With `grouped=1` the page comes wrapped with autosave sessions and the total version count; `before` requests the window of versions strictly older than the given version number, and `pinnedVersion` forces a published version into the first page.",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "required": true,
            "description": "Id of the artifact.",
            "schema": {
              "examples": [
                "ntCPN9GXCyCkoZ1X"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "grouped",
            "in": "query",
            "required": false,
            "description": "Pass the literal string `1` to receive the grouped shape with autosave sessions and the total version count.",
            "schema": {
              "examples": [
                "1"
              ]
            }
          },
          {
            "name": "pinnedVersion",
            "in": "query",
            "required": false,
            "description": "Version number forced into the first page, used to keep the published version loaded.",
            "schema": {
              "examples": [
                3
              ],
              "type": "number"
            }
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "description": "Requests the window of versions strictly older than this version number, for paging back through history.",
            "schema": {
              "examples": [
                42
              ],
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The artifact versions (a plain array, or the grouped shape when `grouped=1`)",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "Id of the artifact.",
                            "examples": [
                              "ntCPN9GXCyCkoZ1X"
                            ],
                            "type": "string"
                          },
                          "title": {
                            "description": "Title of the artifact.",
                            "examples": [
                              "Launch plan"
                            ],
                            "type": "string"
                          },
                          "content": {
                            "description": "Content of this artifact version.",
                            "type": "string"
                          },
                          "kind": {
                            "description": "Kind of the artifact: `text`, `json`, or `agent-spec`.",
                            "examples": [
                              "text"
                            ],
                            "type": "string"
                          },
                          "version": {
                            "description": "Version number, starting at 1.",
                            "examples": [
                              3
                            ],
                            "type": "number"
                          },
                          "userId": {
                            "description": "Id of the user who owns the artifact.",
                            "type": "number"
                          },
                          "createdAt": {
                            "description": "When the artifact was created, as an ISO 8601 timestamp.",
                            "examples": [
                              "2026-01-15T09:30:00.000Z"
                            ],
                            "type": "string"
                          },
                          "updatedAt": {
                            "description": "When this version was last updated, as an ISO 8601 timestamp.",
                            "examples": [
                              "2026-01-15T10:05:00.000Z"
                            ],
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "title",
                          "content",
                          "kind",
                          "version",
                          "userId",
                          "createdAt",
                          "updatedAt"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    {
                      "type": "object",
                      "properties": {
                        "versions": {
                          "description": "One page of artifact versions, newest first.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "description": "Id of the artifact.",
                                "examples": [
                                  "ntCPN9GXCyCkoZ1X"
                                ],
                                "type": "string"
                              },
                              "title": {
                                "description": "Title of the artifact.",
                                "examples": [
                                  "Launch plan"
                                ],
                                "type": "string"
                              },
                              "content": {
                                "description": "Content of this artifact version.",
                                "type": "string"
                              },
                              "kind": {
                                "description": "Kind of the artifact: `text`, `json`, or `agent-spec`.",
                                "examples": [
                                  "text"
                                ],
                                "type": "string"
                              },
                              "version": {
                                "description": "Version number, starting at 1.",
                                "examples": [
                                  3
                                ],
                                "type": "number"
                              },
                              "userId": {
                                "description": "Id of the user who owns the artifact.",
                                "type": "number"
                              },
                              "createdAt": {
                                "description": "When the artifact was created, as an ISO 8601 timestamp.",
                                "examples": [
                                  "2026-01-15T09:30:00.000Z"
                                ],
                                "type": "string"
                              },
                              "updatedAt": {
                                "description": "When this version was last updated, as an ISO 8601 timestamp.",
                                "examples": [
                                  "2026-01-15T10:05:00.000Z"
                                ],
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "title",
                              "content",
                              "kind",
                              "version",
                              "userId",
                              "createdAt",
                              "updatedAt"
                            ],
                            "additionalProperties": {}
                          }
                        },
                        "autosaveSessions": {
                          "description": "Autosave sessions recorded on the artifact metadata, most recently updated first.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "sessionId": {
                                "description": "Id of the autosave session.",
                                "type": "string"
                              },
                              "startedAt": {
                                "description": "When the session started, as an ISO 8601 timestamp.",
                                "examples": [
                                  "2026-01-15T09:30:00.000Z"
                                ],
                                "type": "string"
                              },
                              "updatedAt": {
                                "description": "When the session last saved, as an ISO 8601 timestamp.",
                                "examples": [
                                  "2026-01-15T09:45:00.000Z"
                                ],
                                "type": "string"
                              },
                              "count": {
                                "description": "Number of autosaves in the session.",
                                "examples": [
                                  12
                                ],
                                "type": "number"
                              }
                            },
                            "required": [
                              "sessionId",
                              "startedAt",
                              "updatedAt",
                              "count"
                            ],
                            "additionalProperties": false
                          }
                        },
                        "totalVersionCount": {
                          "description": "Total number of versions the artifact has, equal to the newest version number.",
                          "examples": [
                            42
                          ],
                          "type": "number"
                        }
                      },
                      "required": [
                        "versions",
                        "autosaveSessions",
                        "totalVersionCount"
                      ],
                      "additionalProperties": false
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Artifact not found"
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "saveArtifact",
        "summary": "Create or update an artifact",
        "tags": [
          "artifacts"
        ],
        "description": "When `artifact.id` matches an existing artifact it is updated (as an unpublished draft when `draft` is true), honouring an optional `If-Match` version precondition; otherwise a new artifact is created in the application collection. `artifact.kind` is a storage-level format (for example `json` or `markdown`). Saving a JSON artifact does not create, link, validate, or publish an Agent; use the semantic `createAgent` operation to create a draft agent and its linked spec artifact.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "applicationId": {
                    "description": "Id of the application. Required when creating an artifact, ignored on updates.",
                    "examples": [
                      7
                    ],
                    "type": "number"
                  },
                  "draft": {
                    "description": "When true, an update overwrites the current version in place instead of creating a new version.",
                    "type": "boolean"
                  },
                  "artifact": {
                    "description": "The artifact fields to save. On updates, missing fields keep their existing values.",
                    "type": "object",
                    "properties": {
                      "id": {
                        "description": "Id of the artifact. When it matches an existing artifact the artifact is updated, otherwise a new one is created.",
                        "examples": [
                          "ntCPN9GXCyCkoZ1X"
                        ],
                        "type": "string"
                      },
                      "content": {
                        "description": "Content of the artifact.",
                        "type": "string"
                      },
                      "title": {
                        "description": "Title of the artifact.",
                        "examples": [
                          "Launch plan"
                        ],
                        "type": "string"
                      },
                      "kind": {
                        "description": "Kind of the artifact: `text`, `json`, or `agent-spec`.",
                        "examples": [
                          "text"
                        ],
                        "type": "string"
                      },
                      "version": {
                        "description": "Version precondition for updates: the expected current version on draft saves, or the desired new version on published saves. The `If-Match` header takes precedence.",
                        "examples": [
                          3
                        ],
                        "type": "number"
                      },
                      "metadata": {
                        "description": "Arbitrary metadata merged into the existing artifact metadata.",
                        "type": "object",
                        "propertyNames": {
                          "type": "string"
                        },
                        "additionalProperties": {}
                      }
                    },
                    "additionalProperties": {}
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The saved artifact (the `ETag` header carries the version on updates)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "Id of the artifact.",
                      "examples": [
                        "ntCPN9GXCyCkoZ1X"
                      ],
                      "type": "string"
                    },
                    "title": {
                      "description": "Title of the artifact.",
                      "examples": [
                        "Launch plan"
                      ],
                      "type": "string"
                    },
                    "content": {
                      "description": "Content of this artifact version.",
                      "type": "string"
                    },
                    "kind": {
                      "description": "Kind of the artifact: `text`, `json`, or `agent-spec`.",
                      "examples": [
                        "text"
                      ],
                      "type": "string"
                    },
                    "version": {
                      "description": "Version number, starting at 1.",
                      "examples": [
                        3
                      ],
                      "type": "number"
                    },
                    "userId": {
                      "description": "Id of the user who owns the artifact.",
                      "type": "number"
                    },
                    "createdAt": {
                      "description": "When the artifact was created, as an ISO 8601 timestamp.",
                      "examples": [
                        "2026-01-15T09:30:00.000Z"
                      ],
                      "type": "string"
                    },
                    "updatedAt": {
                      "description": "When this version was last updated, as an ISO 8601 timestamp.",
                      "examples": [
                        "2026-01-15T10:05:00.000Z"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "title",
                    "content",
                    "kind",
                    "version",
                    "userId",
                    "createdAt",
                    "updatedAt"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "Invalid body",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "412": {
            "description": "Version conflict: the `If-Match` precondition failed"
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/artifacts/{artifactId}/": {
      "delete": {
        "operationId": "deleteArtifact",
        "summary": "Delete an artifact",
        "tags": [
          "artifacts"
        ],
        "description": "A soft delete: the document backing the artifact is marked ARCHIVED, which hides the artifact from listings and lookups. Failures answer 500 with `{ success: false, error }` instead of the standard error shape.",
        "parameters": [
          {
            "name": "artifactId",
            "in": "path",
            "required": true,
            "description": "Id of the artifact.",
            "schema": {
              "examples": [
                "ntCPN9GXCyCkoZ1X"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The artifact was deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the artifact was deleted.",
                      "type": "boolean"
                    },
                    "error": {
                      "description": "Raw error details, present only when the deletion failed."
                    }
                  },
                  "required": [
                    "success"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "The deletion failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the artifact was deleted.",
                      "type": "boolean"
                    },
                    "error": {
                      "description": "Raw error details, present only when the deletion failed."
                    }
                  },
                  "required": [
                    "success"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/artifacts/export/": {
      "post": {
        "operationId": "exportArtifactToCollection",
        "summary": "Export an artifact to a collection as a document",
        "tags": [
          "artifacts"
        ],
        "description": "Renders the selected artifact version (`version`, latest when omitted) as a PDF file and saves it as a new document in the destination collection, which requires write permission. The document then goes through the regular ingestion pipeline. The artifact is named by the `id` body field; the `id` query parameter is the deprecated location and the body value wins when both are given. The `403` responses are plain-text bodies.",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "required": false,
            "description": "Deprecated: pass the artifact id in the request body instead. The body value wins when both are given.",
            "schema": {
              "examples": [
                "ntCPN9GXCyCkoZ1X"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "description": "Id of the artifact to export. Required unless the deprecated `id` query parameter is given; the body value wins when both are present.",
                    "examples": [
                      "ntCPN9GXCyCkoZ1X"
                    ],
                    "type": "string",
                    "minLength": 1
                  },
                  "collectionId": {
                    "description": "Id of the destination collection. The caller needs write permission on it.",
                    "examples": [
                      42
                    ],
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  "version": {
                    "description": "Artifact version to export. Defaults to the latest version.",
                    "examples": [
                      3
                    ],
                    "type": "number"
                  },
                  "mimeType": {
                    "description": "Accepted for backward compatibility and no longer used. The export always renders the artifact as a PDF.",
                    "examples": [
                      "text/markdown"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "collectionId"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The document created from the artifact",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the artifact was exported.",
                      "type": "boolean"
                    },
                    "document": {
                      "description": "The document created in the destination collection.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "Id of the newly created document.",
                          "examples": [
                            128
                          ],
                          "type": "number"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "success",
                    "document"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "No artifact id in the body or the query string",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No write access to the collection"
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/messages/{id}/": {
      "get": {
        "operationId": "getMessageById",
        "summary": "Get a message by id",
        "tags": [
          "messages"
        ],
        "description": "Requires access to the associated application, or ownership when the message has no application. The message is sanitized before returning: oversized metadata fields such as `originalMediaUrl` are removed. Failure responses are plain-text bodies.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id of the message.",
            "schema": {
              "examples": [
                "cm4xk3q8e0002abcd12345678"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The sanitized message, including its author",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "Id of the message.",
                      "type": "string"
                    },
                    "role": {
                      "description": "Author role of the message: `USER`, `ASSISTANT`, `SYSTEM`, or `TOOL`.",
                      "examples": [
                        "USER"
                      ],
                      "type": "string"
                    },
                    "content": {
                      "description": "Content of the message: a string, or an array of parts. Attachment file parts carry the `documentId` of the ingested attachment, a `url` pointing at `GET /api/v1/documents/{documentId}/download/` (authenticated), and a `viewUrl` — a time-limited pre-authorized link to the same bytes that can be fetched, rendered or attached without platform credentials (it expires after a few hours; re-fetch the message for a fresh one). Document URLs embedded in tool results (for example a search result’s `downloadUrl`) carry the same time-limited `vid` token and are directly fetchable too. The transcription or extracted text of that attachment is available at `GET /api/v1/documents/{documentId}/content/`."
                    },
                    "attachmentRepair": {
                      "description": "Present only when inline WhatsApp attachment bytes could not be safely recovered.",
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "const": "PARTIAL"
                        },
                        "unavailablePartIndexes": {
                          "type": "array",
                          "items": {
                            "type": "integer",
                            "minimum": 0,
                            "maximum": 9007199254740991
                          }
                        }
                      },
                      "required": [
                        "status",
                        "unavailablePartIndexes"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "id",
                    "role",
                    "content"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "202": {
            "description": "Inline WhatsApp attachments are being converted to documents; retry after two seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "attachmentRepair": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "const": "PROCESSING"
                        }
                      },
                      "required": [
                        "status"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "id",
                    "attachmentRepair"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The caller has no access to the message or its application"
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Message not found"
          },
          "409": {
            "description": "Message changed while its attachments were being converted; retry the request.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "attachmentRepair": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "const": "CONFLICT"
                        }
                      },
                      "required": [
                        "status"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "id",
                    "attachmentRepair"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Attachment ingestion is temporarily unavailable; retry after two seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "attachmentRepair": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "const": "RETRY"
                        }
                      },
                      "required": [
                        "status"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "id",
                    "attachmentRepair"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "patchMessageContext",
        "summary": "Patch a message context",
        "tags": [
          "messages"
        ],
        "description": "Requires application-admin access. Session authentication is accepted; when an API key header is present it must have `FULL` scope. Only the internal message id is accepted. Context is shallow-merged, null removes top-level keys, and `context.role` synchronizes metadata origin.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id of the message.",
            "schema": {
              "examples": [
                "cm4xk3q8e0002abcd12345678"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Strict context patch (maximum 16 KiB).",
          "content": {
            "application/json": {
              "schema": {
                "description": "A strict JSON object containing a non-empty context patch. It shallow-merges context and null removes top-level keys. The body and resulting context are limited to 16 KiB; patches allow 32 keys, results 64 keys, nesting depth 4, arrays of 50, and strings of 2048 characters. Sensitive, internal, and prototype-pollution keys are rejected recursively.",
                "type": "object",
                "properties": {
                  "context": {
                    "description": "Context fields to merge. Null removes a top-level field; objects and arrays replace the existing value.",
                    "examples": [
                      {
                        "role": "HUMAN_ASSISTANT",
                        "ticket": "T-1",
                        "priority": null
                      }
                    ],
                    "type": "object",
                    "properties": {
                      "role": {
                        "anyOf": [
                          {
                            "type": "string",
                            "enum": [
                              "USER",
                              "ASSISTANT",
                              "HUMAN_ASSISTANT"
                            ]
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "additionalProperties": {}
                  }
                },
                "required": [
                  "context"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The bounded updated context response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "Internal message id.",
                      "examples": [
                        "cm4xk3q8e0002abcd12345678"
                      ],
                      "type": "string"
                    },
                    "context": {
                      "description": "Updated message metadata context.",
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {}
                    },
                    "origin": {
                      "description": "Origin synchronized from context.role, when present.",
                      "anyOf": [
                        {
                          "type": "string",
                          "enum": [
                            "USER",
                            "ASSISTANT",
                            "HUMAN_ASSISTANT"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "updatedAt": {
                      "description": "When the message was last updated, as an ISO 8601 timestamp.",
                      "examples": [
                        "2026-07-14T12:00:00.000Z"
                      ],
                      "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))$"
                    }
                  },
                  "required": [
                    "id",
                    "context",
                    "origin",
                    "updatedAt"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON, patch shape, or context limits.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed or API key is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "403": {
            "description": "Caller is not an application administrator or has insufficient API key scope.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Message not found.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/document-templates/import/": {
      "post": {
        "operationId": "importDocumentTemplate",
        "summary": "Import a document template bundle",
        "tags": [
          "document-templates"
        ],
        "description": "Imports an exported document template bundle into an application. Accepts `application/json` or `multipart/form-data` with a `file` field. `applicationId` comes from the payload or the query string.",
        "parameters": [
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "targetTemplateId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "The exported document template bundle. Also accepted as `multipart/form-data` with the bundle JSON in a `file` field and optional `applicationId` / `targetTemplateId` fields.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "exportVersion": {
                    "type": "number",
                    "minimum": 1
                  },
                  "template": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string",
                        "minLength": 1
                      },
                      "description": {
                        "default": "",
                        "type": "string"
                      },
                      "content": {
                        "default": "",
                        "type": "string"
                      },
                      "metadata": {
                        "default": {},
                        "type": "object",
                        "propertyNames": {
                          "type": "string"
                        },
                        "additionalProperties": {}
                      },
                      "type": {
                        "default": "DOCUMENT",
                        "type": "string",
                        "const": "DOCUMENT"
                      }
                    },
                    "required": [
                      "name"
                    ]
                  }
                },
                "required": [
                  "exportVersion",
                  "template"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Import summary with the created or updated template id",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "documentTemplateId": {
                      "type": "string"
                    },
                    "created": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "ok",
                    "documentTemplateId",
                    "created"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid payload or missing applicationId",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Import failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/document-templates/import/check/": {
      "post": {
        "operationId": "checkDocumentTemplateImport",
        "summary": "Check whether a document template import bundle already exists",
        "tags": [
          "document-templates"
        ],
        "description": "Inspects an export bundle and reports whether the template already exists in the target application. Accepts `application/json` or `multipart/form-data` with a `file` field.",
        "requestBody": {
          "required": true,
          "description": "The exported document template bundle to check. Also accepted as `multipart/form-data` with the bundle JSON in a `file` field and an optional `applicationId` field.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "exportVersion": {
                    "type": "number",
                    "minimum": 1
                  },
                  "template": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string",
                        "minLength": 1
                      },
                      "description": {
                        "default": "",
                        "type": "string"
                      },
                      "content": {
                        "default": "",
                        "type": "string"
                      },
                      "metadata": {
                        "default": {},
                        "type": "object",
                        "propertyNames": {
                          "type": "string"
                        },
                        "additionalProperties": {}
                      },
                      "type": {
                        "default": "DOCUMENT",
                        "type": "string",
                        "const": "DOCUMENT"
                      }
                    },
                    "required": [
                      "name"
                    ]
                  }
                },
                "required": [
                  "exportVersion",
                  "template"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Existence report for the template bundle",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "exists": {
                      "type": "boolean"
                    },
                    "templateName": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "existingTemplate": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id",
                            "name"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "templateType": {
                      "type": "string",
                      "const": "DOCUMENT"
                    }
                  },
                  "required": [
                    "exists",
                    "templateName",
                    "existingTemplate",
                    "templateType"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid payload or missing applicationId",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Check failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/document-templates/{documentTemplateId}/export/": {
      "get": {
        "operationId": "exportDocumentTemplate",
        "summary": "Export a document template bundle",
        "tags": [
          "document-templates"
        ],
        "description": "Exports a document template as a portable JSON bundle. Served as a file download (`Content-Disposition: attachment`).",
        "parameters": [
          {
            "name": "documentTemplateId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The exported document template bundle as a file download"
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the template",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Template not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/collections/": {
      "get": {
        "operationId": "listCollections",
        "summary": "List collections",
        "tags": [
          "knowledge"
        ],
        "description": "With `applicationId` the list contains the collections attached to that application, otherwise every collection of the caller’s company that the caller can see. `libraryId` narrows either list to one library. Only ACTIVE collections are returned.",
        "parameters": [
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Lists the collections attached to this application instead of the whole company.",
            "schema": {
              "examples": [
                7
              ],
              "type": "integer",
              "minimum": -9007199254740991,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "skipApplicationCollections",
            "in": "query",
            "required": false,
            "description": "Pass the literal string `true` to exclude the internal application collection from an application-scoped list. Any other value disables the flag.",
            "schema": {
              "examples": [
                "true"
              ]
            }
          },
          {
            "name": "libraryId",
            "in": "query",
            "required": false,
            "description": "Narrows the list to collections of this library.",
            "schema": {
              "examples": [
                3
              ],
              "type": "integer",
              "minimum": -9007199254740991,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The collections visible to the caller",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "description": "Id of the collection.",
                        "examples": [
                          42
                        ],
                        "type": "number"
                      },
                      "userId": {
                        "description": "Id of the user who created the collection.",
                        "type": "number"
                      },
                      "companyId": {
                        "description": "Id of the company that owns the collection.",
                        "type": "number"
                      },
                      "name": {
                        "description": "Name of the collection.",
                        "examples": [
                          "Product specs"
                        ],
                        "type": "string"
                      },
                      "libraryId": {
                        "description": "Id of the library the collection belongs to.",
                        "examples": [
                          3
                        ],
                        "type": "number"
                      }
                    },
                    "required": [
                      "id",
                      "userId",
                      "companyId",
                      "name",
                      "libraryId"
                    ],
                    "additionalProperties": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createCollection",
        "summary": "Create a collection",
        "tags": [
          "knowledge"
        ],
        "description": "Body: `{ name, description?, icon?, isPrivate?, libraryId }`. Validation failures answer `400 { error: \"Validation failed\", details }`.",
        "requestBody": {
          "required": true,
          "description": "The collection to create.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "description": "Name of the collection.",
                    "examples": [
                      "Product specs"
                    ],
                    "type": "string",
                    "minLength": 1
                  },
                  "description": {
                    "description": "Description of the collection.",
                    "type": "string"
                  },
                  "icon": {
                    "description": "Name of the icon shown next to the collection. Defaults to an empty string.",
                    "examples": [
                      "folder"
                    ],
                    "type": "string"
                  },
                  "isPrivate": {
                    "description": "Whether the collection is private to its owner instead of visible to the company. Defaults to false.",
                    "default": false,
                    "type": "boolean"
                  },
                  "libraryId": {
                    "description": "Id of the library the collection is created in.",
                    "examples": [
                      3
                    ],
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  }
                },
                "required": [
                  "name",
                  "libraryId"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created collection",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "Id of the collection.",
                      "examples": [
                        42
                      ],
                      "type": "number"
                    },
                    "userId": {
                      "description": "Id of the user who created the collection.",
                      "type": "number"
                    },
                    "companyId": {
                      "description": "Id of the company that owns the collection.",
                      "type": "number"
                    },
                    "name": {
                      "description": "Name of the collection.",
                      "examples": [
                        "Product specs"
                      ],
                      "type": "string"
                    },
                    "libraryId": {
                      "description": "Id of the library the collection belongs to.",
                      "examples": [
                        3
                      ],
                      "type": "number"
                    }
                  },
                  "required": [
                    "id",
                    "userId",
                    "companyId",
                    "name",
                    "libraryId"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON body or validation failure",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No permission to create collections",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/collections/{collectionId}/": {
      "get": {
        "operationId": "getCollection",
        "summary": "Get a collection",
        "tags": [
          "knowledge"
        ],
        "description": "Returns one ACTIVE collection in the same item shape as the `GET /api/collections/` list. Access follows the shared collection visibility rules (owner, member, application member, or public).",
        "parameters": [
          {
            "name": "collectionId",
            "in": "path",
            "required": true,
            "description": "Id of the collection.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The collection",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "Id of the collection.",
                      "examples": [
                        42
                      ],
                      "type": "number"
                    },
                    "userId": {
                      "description": "Id of the user who created the collection.",
                      "type": "number"
                    },
                    "companyId": {
                      "description": "Id of the company that owns the collection.",
                      "type": "number"
                    },
                    "name": {
                      "description": "Name of the collection.",
                      "examples": [
                        "Product specs"
                      ],
                      "type": "string"
                    },
                    "libraryId": {
                      "description": "Id of the library the collection belongs to.",
                      "examples": [
                        3
                      ],
                      "type": "number"
                    }
                  },
                  "required": [
                    "id",
                    "userId",
                    "companyId",
                    "name",
                    "libraryId"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the collection",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Collection not found or not ACTIVE",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateCollection",
        "summary": "Update a collection",
        "tags": [
          "knowledge"
        ],
        "description": "Updates any subset of `name`, `description`, `icon`, and `isPrivate`; `libraryId` moves the collection to another library. Moving into a private library also makes the collection (and its documents) private.",
        "parameters": [
          {
            "name": "collectionId",
            "in": "path",
            "required": true,
            "description": "Id of the collection.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "description": "New name of the collection.",
                    "examples": [
                      "Product specs"
                    ],
                    "type": "string",
                    "minLength": 1
                  },
                  "description": {
                    "description": "New description of the collection.",
                    "type": "string"
                  },
                  "icon": {
                    "description": "Name of the icon shown next to the collection.",
                    "examples": [
                      "folder"
                    ],
                    "type": "string"
                  },
                  "isPrivate": {
                    "description": "Whether the collection is private to its owner instead of visible to the company.",
                    "type": "boolean"
                  },
                  "libraryId": {
                    "description": "Moves the collection to this library. Moving into a private library also makes the collection private.",
                    "examples": [
                      3
                    ],
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated collection",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "Id of the collection.",
                      "examples": [
                        42
                      ],
                      "type": "number"
                    },
                    "userId": {
                      "description": "Id of the user who created the collection.",
                      "type": "number"
                    },
                    "companyId": {
                      "description": "Id of the company that owns the collection.",
                      "type": "number"
                    },
                    "name": {
                      "description": "Name of the collection.",
                      "examples": [
                        "Product specs"
                      ],
                      "type": "string"
                    },
                    "libraryId": {
                      "description": "Id of the library the collection belongs to.",
                      "examples": [
                        3
                      ],
                      "type": "number"
                    }
                  },
                  "required": [
                    "id",
                    "userId",
                    "companyId",
                    "name",
                    "libraryId"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "Invalid body",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No permission to edit the collection",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Collection not found or not ACTIVE",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteCollection",
        "summary": "Archive a collection",
        "tags": [
          "knowledge"
        ],
        "description": "Soft delete: archives the collection together with its documents and repositories. Archived collections disappear from every listing and their knowledge stops being retrievable.",
        "parameters": [
          {
            "name": "collectionId",
            "in": "path",
            "required": true,
            "description": "Id of the collection.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Archival confirmation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the collection was archived.",
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "success"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No permission to delete the collection",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Collection not found or not ACTIVE",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/libraries/": {
      "get": {
        "operationId": "listLibraries",
        "summary": "List libraries",
        "tags": [
          "knowledge"
        ],
        "description": "With `applicationId` the list contains the libraries of the collections attached to that application, otherwise every library of the caller’s company that the caller can see. The company-wide list is served from cache.",
        "parameters": [
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Lists the libraries attached to this application instead of the whole company.",
            "schema": {
              "examples": [
                7
              ],
              "type": "integer",
              "minimum": -9007199254740991,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "responseShape",
            "in": "query",
            "required": false,
            "description": "Response shape. Omit or use `full` for the legacy array; use `summary` for the lean, cursor-paginated `{ libraries, nextCursor }` envelope.",
            "schema": {
              "examples": [
                "summary"
              ],
              "type": "string",
              "enum": [
                "full",
                "summary"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size in summary mode, from 1 to 100. Defaults to 50.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Opaque cursor returned by a previous summary response. Results are ordered by id ascending.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The libraries visible to the caller. Summary mode returns `{ libraries, nextCursor }`.",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "Id of the library.",
                            "examples": [
                              3
                            ],
                            "type": "number"
                          },
                          "userId": {
                            "description": "Id of the user who created the library.",
                            "type": "number"
                          },
                          "companyId": {
                            "description": "Id of the company that owns the library.",
                            "type": "number"
                          },
                          "name": {
                            "description": "Name of the library.",
                            "examples": [
                              "Engineering"
                            ],
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "userId",
                          "companyId",
                          "name"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    {
                      "type": "object",
                      "properties": {
                        "libraries": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "description": "Id of the library.",
                                "examples": [
                                  3
                                ],
                                "type": "number"
                              },
                              "name": {
                                "description": "Name of the library.",
                                "examples": [
                                  "Engineering"
                                ],
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "name"
                            ],
                            "additionalProperties": false
                          }
                        },
                        "nextCursor": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "libraries",
                        "nextCursor"
                      ],
                      "additionalProperties": false
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createLibrary",
        "summary": "Create a library",
        "tags": [
          "knowledge"
        ],
        "description": "Body: `{ name, isPrivate? }`. Validation failures answer `400 { error: \"Validation failed\", details }`.",
        "requestBody": {
          "required": true,
          "description": "The library to create.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "description": "Name of the library.",
                    "examples": [
                      "Engineering"
                    ],
                    "type": "string",
                    "minLength": 1
                  },
                  "isPrivate": {
                    "description": "Whether the library is private to its owner instead of visible to the company. Defaults to false.",
                    "default": false,
                    "type": "boolean"
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created library",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "Id of the library.",
                      "examples": [
                        3
                      ],
                      "type": "number"
                    },
                    "userId": {
                      "description": "Id of the user who created the library.",
                      "type": "number"
                    },
                    "companyId": {
                      "description": "Id of the company that owns the library.",
                      "type": "number"
                    },
                    "name": {
                      "description": "Name of the library.",
                      "examples": [
                        "Engineering"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "userId",
                    "companyId",
                    "name"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON body or validation failure",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No permission to create libraries",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/documents/{id}/": {
      "get": {
        "operationId": "getDocument",
        "summary": "Get a document",
        "tags": [
          "knowledge"
        ],
        "description": "Returns one document with its user, collection, and summarized knowledge entries. Documents outside the caller’s visibility answer 404.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id of the document.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The document",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "Id of the document.",
                      "examples": [
                        42
                      ],
                      "type": "number"
                    },
                    "userId": {
                      "description": "Id of the user who uploaded the document.",
                      "type": "number"
                    },
                    "companyId": {
                      "description": "Id of the company that owns the document.",
                      "type": "number"
                    },
                    "collectionId": {
                      "description": "Id of the collection the document belongs to.",
                      "examples": [
                        12
                      ],
                      "type": "number"
                    },
                    "status": {
                      "description": "Processing status of the document: `NONE`, `QUEUED`, `PROCESSING`, `COMPLETED`, `FAILED`, or `ARCHIVED`.",
                      "examples": [
                        "COMPLETED"
                      ],
                      "type": "string"
                    },
                    "file": {
                      "description": "Stored file descriptor (filename, mimetype, extension, size)."
                    },
                    "metadata": {
                      "description": "Document metadata. Contains the `title` when one has been set or generated."
                    },
                    "downloadUrl": {
                      "description": "Stable download endpoint for the file bytes. Requires platform credentials.",
                      "examples": [
                        "https://platform.docana.com/api/v1/documents/42/download/"
                      ],
                      "type": "string"
                    },
                    "viewUrl": {
                      "description": "Time-limited pre-authorized link to the same file bytes. It can be fetched, rendered or attached without platform credentials, and expires after a few hours — request the document again for a fresh one. Omitted when a link could not be minted.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "userId",
                    "companyId",
                    "collectionId",
                    "status",
                    "file",
                    "metadata"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Document not found or not visible to the caller",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateDocument",
        "summary": "Rename a document",
        "tags": [
          "knowledge"
        ],
        "description": "Updates the user-facing filename and/or title of a document. The stored file extension is preserved, and an empty `title` clears the user-defined title. Requires write access to the document’s collection.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id of the document.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "filename": {
                    "description": "New user-facing filename. The stored file extension is preserved even when the new name omits it.",
                    "examples": [
                      "Q3 contract.pdf"
                    ],
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 512
                  },
                  "title": {
                    "description": "New title of the document. An empty string clears the user-defined title.",
                    "examples": [
                      "Q3 supplier contract"
                    ],
                    "type": "string",
                    "maxLength": 300
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated document",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "Id of the document.",
                      "examples": [
                        42
                      ],
                      "type": "number"
                    },
                    "userId": {
                      "description": "Id of the user who uploaded the document.",
                      "type": "number"
                    },
                    "companyId": {
                      "description": "Id of the company that owns the document.",
                      "type": "number"
                    },
                    "collectionId": {
                      "description": "Id of the collection the document belongs to.",
                      "examples": [
                        12
                      ],
                      "type": "number"
                    },
                    "status": {
                      "description": "Processing status of the document: `NONE`, `QUEUED`, `PROCESSING`, `COMPLETED`, `FAILED`, or `ARCHIVED`.",
                      "examples": [
                        "COMPLETED"
                      ],
                      "type": "string"
                    },
                    "file": {
                      "description": "Stored file descriptor (filename, mimetype, extension, size)."
                    },
                    "metadata": {
                      "description": "Document metadata. Contains the `title` when one has been set or generated."
                    },
                    "downloadUrl": {
                      "description": "Stable download endpoint for the file bytes. Requires platform credentials.",
                      "examples": [
                        "https://platform.docana.com/api/v1/documents/42/download/"
                      ],
                      "type": "string"
                    },
                    "viewUrl": {
                      "description": "Time-limited pre-authorized link to the same file bytes. It can be fetched, rendered or attached without platform credentials, and expires after a few hours — request the document again for a fresh one. Omitted when a link could not be minted.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "userId",
                    "companyId",
                    "collectionId",
                    "status",
                    "file",
                    "metadata"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or filename",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No write access to the document’s collection",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Document not found or not visible to the caller",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteDocument",
        "summary": "Delete a document",
        "tags": [
          "knowledge"
        ],
        "description": "Soft delete: the document is archived and its knowledge entries stop being retrievable. Requires write access to the document’s collection.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id of the document.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deletion confirmation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the document was deleted.",
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "success"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No write access to the document’s collection",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Document not found or not visible to the caller",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/documents/{id}/status/": {
      "get": {
        "operationId": "getDocumentStatus",
        "summary": "Get the processing status of a document",
        "tags": [
          "knowledge"
        ],
        "description": "Intended for polling after an upload: the status moves from `QUEUED` through `PROCESSING` to `COMPLETED` or `FAILED` once ingestion finishes. The response is never cached.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id of the document.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The document id and its processing status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "Id of the document.",
                      "examples": [
                        42
                      ],
                      "type": "number"
                    },
                    "status": {
                      "description": "Processing status of the document: `NONE`, `QUEUED`, `PROCESSING`, `COMPLETED`, `FAILED`, or `ARCHIVED`.",
                      "examples": [
                        "COMPLETED"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "status"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid document id",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Document not found or not accessible"
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/documents/{id}/content/": {
      "get": {
        "operationId": "getDocumentContent",
        "summary": "Get the extracted text content of a document",
        "tags": [
          "knowledge"
        ],
        "description": "Returns the parsed text of a processed document as ordered chunks. For audio and video documents each chunk is the transcription of one time window, with `startOffsetSec`/`endOffsetSec` locating it on the media timeline. Content is only returned once ingestion is `COMPLETED` — poll `GET /api/v1/documents/{id}/status/` first; any other status (including `FAILED`) answers an empty `chunks` page.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id of the document.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-based page number. Values below 1 are treated as 1. Defaults to 1.",
            "schema": {
              "examples": [
                1
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size, clamped to 1-500. Defaults to 100.",
            "schema": {
              "examples": [
                100
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "One page of the document content chunks.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "Id of the document.",
                      "examples": [
                        42
                      ],
                      "type": "number"
                    },
                    "status": {
                      "description": "Processing status of the document. Content is returned only for `COMPLETED` documents; every other status (including `FAILED`) answers an empty `chunks` page, since an unfinished ingestion may have written partial rows.",
                      "examples": [
                        "COMPLETED"
                      ],
                      "type": "string"
                    },
                    "version": {
                      "description": "Document version the chunks belong to.",
                      "examples": [
                        1
                      ],
                      "type": "number"
                    },
                    "chunks": {
                      "description": "One page of chunks in document order.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "index": {
                            "description": "Zero-based position of the chunk within the document.",
                            "examples": [
                              0
                            ],
                            "type": "number"
                          },
                          "content": {
                            "description": "Extracted text of this chunk. For audio/video documents this is the transcription of one time window.",
                            "examples": [
                              "# Timestamp: [00:00 - 01:00]\n\n# Transcription:\nGood afternoon, I would like to..."
                            ],
                            "type": "string"
                          },
                          "startOffsetSec": {
                            "description": "Start of the transcribed window in seconds. Audio and video documents only.",
                            "type": "number"
                          },
                          "endOffsetSec": {
                            "description": "End of the transcribed window in seconds. Audio and video documents only.",
                            "type": "number"
                          }
                        },
                        "required": [
                          "index",
                          "content"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "totalCount": {
                      "description": "Total number of chunks in the document across all pages.",
                      "type": "number"
                    }
                  },
                  "required": [
                    "id",
                    "status",
                    "version",
                    "chunks",
                    "totalCount"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid document id or pagination values",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Document not found or not accessible"
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/documents/{id}/threads/": {
      "get": {
        "operationId": "listDocumentThreads",
        "summary": "List assistant threads of a document",
        "tags": [
          "knowledge"
        ],
        "description": "`limit` is clamped to 1-100 (default 50) and `page` is 1-based (values below 1 are treated as 1).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id of the document.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Free-text filter matched case-insensitively against thread ids, descriptions, metadata, agent names, and participant names or emails.",
            "schema": {
              "examples": [
                "pricing"
              ]
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-based page number. Values below 1 are treated as 1. Defaults to 1.",
            "schema": {
              "examples": [
                1
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size, clamped to 1-100. Defaults to 50.",
            "schema": {
              "examples": [
                50
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "One page of threads with the total count",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "threads": {
                      "description": "One page of threads, most recently updated first.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "Id of the thread.",
                            "examples": [
                              "cm4xk2p9d0001abcd12345678"
                            ],
                            "type": "string"
                          },
                          "type": {
                            "description": "Type of the thread, always `ASSISTANT` for this endpoint.",
                            "examples": [
                              "ASSISTANT"
                            ],
                            "type": "string"
                          },
                          "archived": {
                            "description": "Whether the thread is archived.",
                            "type": "boolean"
                          },
                          "metadata": {
                            "description": "Thread metadata. Contains the `documentId` the thread is attached to."
                          },
                          "messages": {
                            "description": "The latest user message of the thread, at most one element.",
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "description": "Id of the message.",
                                  "type": "string"
                                },
                                "role": {
                                  "description": "Author role of the message: `USER`, `ASSISTANT`, `SYSTEM`, or `TOOL`.",
                                  "examples": [
                                    "USER"
                                  ],
                                  "type": "string"
                                },
                                "content": {
                                  "description": "Content of the message: a string, or an array of parts. Attachment file parts carry the `documentId` of the ingested attachment, a `url` pointing at `GET /api/v1/documents/{documentId}/download/` (authenticated), and a `viewUrl` — a time-limited pre-authorized link to the same bytes that can be fetched, rendered or attached without platform credentials (it expires after a few hours; re-fetch the message for a fresh one). Document URLs embedded in tool results (for example a search result’s `downloadUrl`) carry the same time-limited `vid` token and are directly fetchable too. The transcription or extracted text of that attachment is available at `GET /api/v1/documents/{documentId}/content/`."
                                }
                              },
                              "required": [
                                "id",
                                "role",
                                "content"
                              ],
                              "additionalProperties": {}
                            }
                          }
                        },
                        "required": [
                          "id",
                          "type",
                          "archived",
                          "metadata",
                          "messages"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "totalCount": {
                      "description": "Total number of threads matching the filter across all pages.",
                      "type": "number"
                    }
                  },
                  "required": [
                    "threads",
                    "totalCount"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid document id or query parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Document not found or not accessible",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/documents/{id}/export/": {
      "post": {
        "operationId": "exportDocumentToCollection",
        "summary": "Copy a document into another collection",
        "tags": [
          "knowledge"
        ],
        "description": "Takes the source document id as the `id` path parameter and a JSON body `{ collectionId }` (destination collection). Failure responses other than the invalid-id 400 are plain-text bodies.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id of the document.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "The destination collection, checked by the handler which answers 400 when `collectionId` is missing.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "collectionId": {
                    "description": "Id of the destination collection the document is copied into. A numeric string is also accepted.",
                    "examples": [
                      12
                    ],
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  }
                },
                "required": [
                  "collectionId"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The copied document",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the document was copied.",
                      "type": "boolean"
                    },
                    "document": {
                      "description": "The copy created in the destination collection.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "Id of the newly created document.",
                          "examples": [
                            128
                          ],
                          "type": "number"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "success",
                    "document"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid document id (standard shape) or missing collectionId (plain-text body)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No write permission on the destination collection (plain-text body)"
          },
          "404": {
            "description": "Source document not found (plain-text body)"
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/search/": {
      "post": {
        "operationId": "searchDocuments",
        "summary": "Search documents semantically",
        "tags": [
          "search"
        ],
        "description": "Body accepts the semantic-search arguments described below.",
        "requestBody": {
          "required": true,
          "description": "The semantic-search arguments.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "query": {
                    "description": "Natural-language search query, up to 1000 characters.",
                    "examples": [
                      "quarterly revenue targets"
                    ],
                    "type": "string",
                    "maxLength": 1000
                  },
                  "applicationId": {
                    "description": "Restricts the search to the collections of this application.",
                    "examples": [
                      7
                    ],
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "collectionIds": {
                    "description": "Restricts the search to these collections. The caller must have access to every id.",
                    "examples": [
                      [
                        12,
                        34
                      ]
                    ],
                    "type": "array",
                    "items": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    }
                  },
                  "documentIds": {
                    "description": "Restricts the search to these documents.",
                    "examples": [
                      [
                        42
                      ]
                    ],
                    "type": "array",
                    "items": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    }
                  },
                  "take": {
                    "description": "Maximum number of documents in the response. Defaults to 50.",
                    "examples": [
                      50
                    ],
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 10000
                  },
                  "maxK": {
                    "description": "Maximum number of knowledge chunks retrieved before grouping by document. Defaults to 50.",
                    "examples": [
                      50
                    ],
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 10000
                  },
                  "score": {
                    "description": "Minimum similarity score between 0 and 1. Chunks scoring below it are filtered out. Defaults to 0.6.",
                    "examples": [
                      0.6
                    ],
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1
                  },
                  "version": {
                    "description": "Document version whose knowledge entries are searched. Defaults to 1.",
                    "examples": [
                      1
                    ],
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "type": {
                    "description": "Restricts results to one knowledge entry type: `CHUNK` (original document chunks) or `SUMMARIZED` (document summaries).",
                    "examples": [
                      "CHUNK"
                    ],
                    "type": "string",
                    "enum": [
                      "CHUNK",
                      "SUMMARIZED"
                    ]
                  },
                  "redirectUrl": {
                    "description": "Not used by the search itself. Accepted for backward compatibility.",
                    "type": "string"
                  }
                },
                "required": [
                  "query"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Search results grouped by document",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "document": {
                        "description": "The matched document.",
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "Id of the document.",
                            "examples": [
                              42
                            ],
                            "type": "number"
                          }
                        },
                        "required": [
                          "id"
                        ],
                        "additionalProperties": {}
                      },
                      "knowledge": {
                        "description": "Knowledge chunks of this document that matched the query, most relevant first.",
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "description": "Id of the knowledge entry.",
                              "examples": [
                                9001
                              ],
                              "type": "number"
                            },
                            "content": {
                              "description": "Text content of the matched chunk.",
                              "type": "string"
                            }
                          },
                          "required": [
                            "id",
                            "content"
                          ],
                          "additionalProperties": {}
                        }
                      },
                      "summary": {
                        "description": "Summary of the document when one has been generated.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "document",
                      "knowledge"
                    ],
                    "additionalProperties": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid search request (with zod `issues`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/search/warmup/": {
      "post": {
        "operationId": "warmupSearchEmbeddings",
        "summary": "Pre-warm the embedding cache for a search query",
        "tags": [
          "search"
        ],
        "description": "Generates the text and multimodal embeddings for the query and stores them in the embedding cache, so a following `POST /api/v1/search/` call with the same query reads them from cache instead of waiting on the embedding service. Body: `{ query }` with 5-1000 characters. Validation failures answer `400 { error: \"Invalid query\" }`.",
        "requestBody": {
          "required": true,
          "description": "The query to pre-warm.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "query": {
                    "description": "Search query to embed and cache, 5 to 1000 characters. Send the exact text of the upcoming search so its cache entry matches.",
                    "examples": [
                      "quarterly revenue targets"
                    ],
                    "type": "string",
                    "minLength": 5,
                    "maxLength": 1000
                  }
                },
                "required": [
                  "query"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Both embeddings were generated and cached",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "success"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON body or invalid query",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Embedding generation failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/search/quick/": {
      "get": {
        "operationId": "quickSearchDocuments",
        "summary": "Quick-search documents",
        "tags": [
          "search"
        ],
        "description": "A GET variant of `POST /api/v1/search/` for typeahead-style lookups: it runs the same semantic search with smaller defaults. `limit` and `maxK` default to 10, and `applicationId` optionally scopes the search.",
        "parameters": [
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Restricts the search to the collections of this application.",
            "schema": {
              "examples": [
                7
              ],
              "type": "integer",
              "minimum": -9007199254740991,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Natural-language search query. Defaults to an empty string.",
            "schema": {
              "examples": [
                "onboarding checklist"
              ],
              "default": "",
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of documents in the response. Defaults to 10.",
            "schema": {
              "examples": [
                10
              ],
              "default": 10,
              "type": "integer",
              "minimum": -9007199254740991,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "maxK",
            "in": "query",
            "required": false,
            "description": "Maximum number of knowledge chunks retrieved before grouping by document. Defaults to 10.",
            "schema": {
              "examples": [
                10
              ],
              "default": 10,
              "type": "integer",
              "minimum": -9007199254740991,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Search results grouped by document",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "document": {
                        "description": "The matched document.",
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "Id of the document.",
                            "examples": [
                              42
                            ],
                            "type": "number"
                          }
                        },
                        "required": [
                          "id"
                        ],
                        "additionalProperties": {}
                      },
                      "knowledge": {
                        "description": "Knowledge chunks of this document that matched the query, most relevant first.",
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "description": "Id of the knowledge entry.",
                              "examples": [
                                9001
                              ],
                              "type": "number"
                            },
                            "content": {
                              "description": "Text content of the matched chunk.",
                              "type": "string"
                            }
                          },
                          "required": [
                            "id",
                            "content"
                          ],
                          "additionalProperties": {}
                        }
                      },
                      "summary": {
                        "description": "Summary of the document when one has been generated.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "document",
                      "knowledge"
                    ],
                    "additionalProperties": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/collections/{collectionId}/embeddings/": {
      "post": {
        "operationId": "generateCollectionEmbeddings",
        "summary": "Generate embeddings for a collection in the background",
        "tags": [
          "knowledge"
        ],
        "description": "Optional body: `{ generateText?, generateMultimodal?, force?, batchSize? }`. Returns immediately with the number of entries queued; generation continues in the background.",
        "parameters": [
          {
            "name": "collectionId",
            "in": "path",
            "required": true,
            "description": "Id of the collection whose knowledge entries are embedded.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Generation options. A missing or malformed body is treated as `{}`, so every field falls back to its default.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "generateText": {
                    "description": "Generate text embeddings. Defaults to true. At least one of `generateText` or `generateMultimodal` must be true.",
                    "default": true,
                    "type": "boolean"
                  },
                  "generateMultimodal": {
                    "description": "Generate multimodal embeddings for image entries. Defaults to true.",
                    "default": true,
                    "type": "boolean"
                  },
                  "force": {
                    "description": "Regenerate embeddings that already exist instead of only filling in missing ones. Defaults to false.",
                    "default": false,
                    "type": "boolean"
                  },
                  "batchSize": {
                    "description": "Number of knowledge entries processed per batch, 1 to 50. Defaults to 25.",
                    "examples": [
                      25
                    ],
                    "default": 25,
                    "type": "number",
                    "minimum": 1,
                    "maximum": 50
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Embedding generation started in the background",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when background generation was started.",
                      "type": "boolean"
                    },
                    "message": {
                      "description": "Human-readable status message.",
                      "examples": [
                        "Embedding generation started in background"
                      ],
                      "type": "string"
                    },
                    "collectionId": {
                      "description": "Id of the collection being processed.",
                      "examples": [
                        42
                      ],
                      "type": "number"
                    },
                    "totalEntriesToProcess": {
                      "description": "Number of knowledge entries queued for embedding generation.",
                      "examples": [
                        120
                      ],
                      "type": "number"
                    },
                    "parameters": {
                      "description": "The effective parameters after defaults were applied.",
                      "type": "object",
                      "properties": {
                        "generateText": {
                          "description": "Whether text embeddings are generated.",
                          "type": "boolean"
                        },
                        "generateMultimodal": {
                          "description": "Whether multimodal embeddings are generated.",
                          "type": "boolean"
                        },
                        "force": {
                          "description": "Whether existing embeddings are regenerated.",
                          "type": "boolean"
                        },
                        "batchSize": {
                          "description": "Number of knowledge entries processed per batch.",
                          "type": "number"
                        }
                      },
                      "required": [
                        "generateText",
                        "generateMultimodal",
                        "force",
                        "batchSize"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "collectionId",
                    "totalEntriesToProcess",
                    "parameters"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid collection id or request parameters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validationErrors": {
                      "type": "object",
                      "properties": {
                        "formErrors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldErrors": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "required": [
                        "formErrors",
                        "fieldErrors"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error",
                    "validationErrors"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No write permission on the collection",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/collections/{collectionId}/documents/": {
      "get": {
        "operationId": "listCollectionDocuments",
        "summary": "List documents in a collection",
        "tags": [
          "knowledge"
        ],
        "description": "One page of the collection documents, most recently updated first. When `search` is set, the page is ranked by semantic similarity to the query instead. Requires read access to the collection.",
        "parameters": [
          {
            "name": "collectionId",
            "in": "path",
            "required": true,
            "description": "Id of the collection.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "When set, ranks the page by semantic similarity to this query instead of recency.",
            "schema": {
              "examples": [
                "payment terms"
              ]
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-based page number. Values below 1 are treated as 1. Defaults to 1.",
            "schema": {
              "examples": [
                1
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size, clamped to 1-100. Defaults to 25.",
            "schema": {
              "examples": [
                25
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "One page of documents with pagination counters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "documents": {
                      "description": "One page of documents, most recently updated first (or by relevance when `search` is set).",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "Id of the document.",
                            "examples": [
                              42
                            ],
                            "type": "number"
                          },
                          "collectionId": {
                            "description": "Id of the collection the document belongs to.",
                            "type": "number"
                          },
                          "status": {
                            "description": "Ingestion status: QUEUED, PROCESSING, PROCESSED, or FAILED.",
                            "examples": [
                              "PROCESSED"
                            ],
                            "type": "string"
                          },
                          "file": {
                            "description": "Stored file descriptor: path, filename, size, mimetype, extension."
                          },
                          "downloadUrl": {
                            "description": "Stable download endpoint for the file bytes. Requires platform credentials.",
                            "examples": [
                              "https://platform.docana.com/api/v1/documents/42/download/"
                            ],
                            "type": "string"
                          },
                          "viewUrl": {
                            "description": "Time-limited pre-authorized link to the same file bytes. It can be fetched, rendered or attached without platform credentials, and expires after a few hours — request the document again for a fresh one. Omitted when a link could not be minted.",
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "collectionId",
                          "status",
                          "file"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "totalCount": {
                      "description": "Total number of documents in the collection (or matching the search).",
                      "type": "number"
                    },
                    "inProgressDocumentCount": {
                      "description": "Documents currently QUEUED or PROCESSING in the collection.",
                      "type": "number"
                    }
                  },
                  "required": [
                    "documents",
                    "totalCount",
                    "inProgressDocumentCount"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "uploadCollectionDocuments",
        "summary": "Upload documents to a collection",
        "tags": [
          "knowledge"
        ],
        "description": "Multipart upload of one or more files into a collection. Large files can use the resumable chunked protocol driven by the `x-resume-token`, `x-resume-from-byte` and `x-total-file-size` request headers (see `src/shared/chunked-upload.ts`); plain multipart posts of the `files` field work without any of them. Requires write permission on the collection.",
        "parameters": [
          {
            "name": "collectionId",
            "in": "path",
            "required": true,
            "description": "Id of the collection.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "The files to ingest, repeated under the `files` field.",
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "files": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "binary",
                      "contentEncoding": "binary"
                    }
                  }
                },
                "required": [
                  "files"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Upload accepted; one entry per uploaded file (or chunk acknowledgement in chunked mode)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "isComplete": {
                      "type": "boolean"
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "success"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No write permission on the collection",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/uploads/": {
      "post": {
        "operationId": "createDocumentUploadUrl",
        "summary": "Create a one-time document upload URL",
        "tags": [
          "knowledge"
        ],
        "description": "The two-step upload for callers that cannot send multipart/form-data (MCP hosts, plain scripts): this operation returns a short-lived, single-use URL, and sending the raw file bytes to it with PUT ingests the file into the collection exactly like a regular upload. The URL inherits the permissions of whoever created it. For files up to ~30MB; larger files should use the multipart endpoint with the resumable chunked protocol.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "collectionId": {
                    "description": "The collection the uploaded document will be ingested into.",
                    "examples": [
                      42
                    ],
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  "filename": {
                    "description": "Name for the document, including its extension.",
                    "examples": [
                      "contract.pdf"
                    ],
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  }
                },
                "required": [
                  "collectionId",
                  "filename"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The upload URL to send the file bytes to",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "uploadUrl": {
                      "description": "One-time absolute URL. Send the raw file bytes to it with the PUT method.",
                      "type": "string"
                    },
                    "method": {
                      "description": "HTTP method the upload URL expects.",
                      "type": "string",
                      "const": "PUT"
                    },
                    "expiresInSeconds": {
                      "description": "Lifetime of the URL. It is also invalidated by its first use.",
                      "type": "number"
                    },
                    "instructions": {
                      "description": "How to perform the upload, e.g. the curl command a shell-capable host can run.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "uploadUrl",
                    "method",
                    "expiresInSeconds",
                    "instructions"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No write permission on the collection",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/uploads/{ticket}/": {
      "put": {
        "operationId": "receiveDocumentUpload",
        "summary": "Send the file bytes for a one-time upload URL",
        "tags": [
          "knowledge"
        ],
        "description": "Second step of the two-step upload: PUT the raw file bytes to the URL returned by `createDocumentUploadUrl`. The URL is single-use and expires; no authentication header is required because the URL itself is the credential.",
        "parameters": [
          {
            "name": "ticket",
            "in": "path",
            "required": true,
            "description": "The one-time token minted by createDocumentUploadUrl.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "The file content, verbatim.",
          "content": {
            "application/octet-stream": {}
          }
        },
        "responses": {
          "200": {
            "description": "Upload accepted; same envelope as the multipart upload endpoint",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "success"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown, expired, or already-used upload URL",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "413": {
            "description": "File larger than the one-time upload limit",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/documents/{id}/download/": {
      "get": {
        "operationId": "downloadDocument",
        "summary": "Download a document",
        "tags": [
          "knowledge"
        ],
        "description": "Streams the document bytes. `size` (e.g. `SMALL`, `MEDIUM`, `LARGE`, `WHATSAPP`) serves a resized variant for images; `pdfPreviewType=image` serves a PDF page rendered as an image. The response content type follows the stored file.",
        "x-docana-streaming": true,
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id of the document.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "size",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "pdfPreviewType",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "image",
                "pdf"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The document bytes (content type of the stored file)"
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the document"
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/evaluation-criteria/": {
      "get": {
        "operationId": "getEvaluationCriteria",
        "summary": "Get an evaluation criteria by id",
        "tags": [
          "evaluation-criteria"
        ],
        "description": "Looks the criteria up within the given application on behalf of the caller. Any lookup failure, including lack of access to the application, answers `404` so the endpoint does not reveal whether the id exists.",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "required": true,
            "description": "Id of the evaluation criteria to fetch.",
            "schema": {
              "examples": [
                "cmb9x2h3k0001l804fy1q8w7e"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "applicationId",
            "in": "query",
            "required": true,
            "description": "Id of the application the evaluation criteria belongs to.",
            "schema": {
              "examples": [
                42
              ],
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The evaluation criteria",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "Id of the evaluation criteria.",
                      "examples": [
                        "cmb9x2h3k0001l804fy1q8w7e"
                      ],
                      "type": "string"
                    },
                    "applicationId": {
                      "description": "Id of the application that owns the criteria.",
                      "examples": [
                        42
                      ],
                      "type": "number"
                    }
                  },
                  "required": [
                    "id",
                    "applicationId"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Evaluation criteria not found or inaccessible",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/mcp-servers/{mcpServerId}/connection/": {
      "get": {
        "operationId": "getMcpServerConnection",
        "summary": "Get the caller’s OAuth connection status for an MCP server",
        "tags": [
          "mcp-servers"
        ],
        "description": "Reports whether the server requires a per-user OAuth connection and, when it does, the state of the caller’s stored tokens (`not_connected`, `connected`, `expiring_soon` or `expired`). Use `GET /api/v1/mcp-servers/oauth/authorize/` to start a new connection.",
        "parameters": [
          {
            "name": "mcpServerId",
            "in": "path",
            "required": true,
            "description": "Id of the MCP server.",
            "schema": {
              "examples": [
                "cmb7q4w1s0003l804m2t6d9ka"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The connection status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "requiresOAuth": {
                      "description": "Whether the MCP server is configured to require a per-user OAuth connection.",
                      "type": "boolean"
                    },
                    "connected": {
                      "description": "Whether the caller currently has a stored OAuth connection. Always false when OAuth is not required.",
                      "type": "boolean"
                    },
                    "status": {
                      "description": "OAuth connection status: `not_connected`, `connected`, `expiring_soon` or `expired`. Null when the server does not require OAuth.",
                      "examples": [
                        "connected"
                      ],
                      "type": "string"
                    },
                    "tokenExpiresAt": {
                      "description": "ISO 8601 expiry time of the stored access token. Null when unknown or not connected.",
                      "examples": [
                        "2026-08-01T12:00:00.000Z"
                      ],
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "connectedAt": {
                      "description": "ISO 8601 time the OAuth connection was first created. Null when not connected.",
                      "examples": [
                        "2026-06-15T09:30:00.000Z"
                      ],
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "updatedAt": {
                      "description": "ISO 8601 time the stored connection was last refreshed. Null when not connected.",
                      "examples": [
                        "2026-07-01T18:45:00.000Z"
                      ],
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "transport": {
                      "description": "Transport the server is configured with: `sse` or `http`. Defaults to `sse`.",
                      "examples": [
                        "sse"
                      ],
                      "type": "string"
                    },
                    "authMethod": {
                      "description": "Authentication method configured on the server: `none`, `bearer` or `oauth`.",
                      "examples": [
                        "oauth"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "requiresOAuth",
                    "connected",
                    "status",
                    "tokenExpiresAt",
                    "connectedAt",
                    "updatedAt",
                    "transport",
                    "authMethod"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "MCP server not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "disconnectMcpServerConnection",
        "summary": "Disconnect the caller’s OAuth connection for an MCP server",
        "tags": [
          "mcp-servers"
        ],
        "description": "Deletes the caller’s stored OAuth tokens for the server. The assistant then skips the server’s tools until the user reconnects via `GET /api/v1/mcp-servers/oauth/authorize/`. Succeeds even when no connection exists.",
        "parameters": [
          {
            "name": "mcpServerId",
            "in": "path",
            "required": true,
            "description": "Id of the MCP server.",
            "schema": {
              "examples": [
                "cmb7q4w1s0003l804m2t6d9ka"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Disconnection confirmation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the stored OAuth connection was deleted.",
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "success"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "A resource referenced by the path does not exist or is not visible to the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/mcp-servers/{mcpServerId}/test-connection/": {
      "post": {
        "operationId": "testMcpServerConnectionById",
        "summary": "Test connectivity to an MCP server",
        "tags": [
          "mcp-servers"
        ],
        "description": "Opens a real client session against the server and lists its tools, so it exercises the configured transport, credentials and, for OAuth servers, the caller’s stored connection. Discovery failures answer `400` with the error message in the same response shape.",
        "parameters": [
          {
            "name": "mcpServerId",
            "in": "path",
            "required": true,
            "description": "Id of the MCP server.",
            "schema": {
              "examples": [
                "cmb7q4w1s0003l804m2t6d9ka"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The discovered tool names",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "Whether tool discovery against the server succeeded.",
                      "type": "boolean"
                    },
                    "toolCount": {
                      "description": "Number of tools the server exposes. Zero when discovery failed.",
                      "examples": [
                        5
                      ],
                      "type": "number"
                    },
                    "toolNames": {
                      "description": "Names of the tools discovered on the server. Empty when discovery failed.",
                      "examples": [
                        [
                          "search_issues",
                          "create_ticket"
                        ]
                      ],
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "error": {
                      "description": "Error message. Present only when discovery failed.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "success",
                    "toolCount",
                    "toolNames"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Tool discovery failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "Whether tool discovery against the server succeeded.",
                      "type": "boolean"
                    },
                    "toolCount": {
                      "description": "Number of tools the server exposes. Zero when discovery failed.",
                      "examples": [
                        5
                      ],
                      "type": "number"
                    },
                    "toolNames": {
                      "description": "Names of the tools discovered on the server. Empty when discovery failed.",
                      "examples": [
                        [
                          "search_issues",
                          "create_ticket"
                        ]
                      ],
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "error": {
                      "description": "Error message. Present only when discovery failed.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "success",
                    "toolCount",
                    "toolNames"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "MCP server not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/mcp-servers/connection/": {
      "get": {
        "operationId": "getMcpServerConnectionByQuery",
        "summary": "Get the caller’s OAuth connection status for an MCP server (deprecated shape)",
        "tags": [
          "mcp-servers"
        ],
        "description": "Deprecated: use `GET /api/v1/mcp-servers/{mcpServerId}/connection/`, which addresses the server in the path instead of a required query parameter. Same payload, same behavior.",
        "deprecated": true,
        "parameters": [
          {
            "name": "mcpServerId",
            "in": "query",
            "required": true,
            "description": "Id of the MCP server.",
            "schema": {
              "examples": [
                "cmb7q4w1s0003l804m2t6d9ka"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The connection status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "requiresOAuth": {
                      "description": "Whether the MCP server is configured to require a per-user OAuth connection.",
                      "type": "boolean"
                    },
                    "connected": {
                      "description": "Whether the caller currently has a stored OAuth connection. Always false when OAuth is not required.",
                      "type": "boolean"
                    },
                    "status": {
                      "description": "OAuth connection status: `not_connected`, `connected`, `expiring_soon` or `expired`. Null when the server does not require OAuth.",
                      "examples": [
                        "connected"
                      ],
                      "type": "string"
                    },
                    "tokenExpiresAt": {
                      "description": "ISO 8601 expiry time of the stored access token. Null when unknown or not connected.",
                      "examples": [
                        "2026-08-01T12:00:00.000Z"
                      ],
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "connectedAt": {
                      "description": "ISO 8601 time the OAuth connection was first created. Null when not connected.",
                      "examples": [
                        "2026-06-15T09:30:00.000Z"
                      ],
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "updatedAt": {
                      "description": "ISO 8601 time the stored connection was last refreshed. Null when not connected.",
                      "examples": [
                        "2026-07-01T18:45:00.000Z"
                      ],
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "transport": {
                      "description": "Transport the server is configured with: `sse` or `http`. Defaults to `sse`.",
                      "examples": [
                        "sse"
                      ],
                      "type": "string"
                    },
                    "authMethod": {
                      "description": "Authentication method configured on the server: `none`, `bearer` or `oauth`.",
                      "examples": [
                        "oauth"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "requiresOAuth",
                    "connected",
                    "status",
                    "tokenExpiresAt",
                    "connectedAt",
                    "updatedAt",
                    "transport",
                    "authMethod"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "MCP server not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "disconnectMcpServerConnectionByQuery",
        "summary": "Disconnect the caller’s OAuth connection for an MCP server (deprecated shape)",
        "tags": [
          "mcp-servers"
        ],
        "description": "Deprecated: use `DELETE /api/v1/mcp-servers/{mcpServerId}/connection/`, which addresses the server in the path instead of a required query parameter. Same behavior.",
        "deprecated": true,
        "parameters": [
          {
            "name": "mcpServerId",
            "in": "query",
            "required": true,
            "description": "Id of the MCP server.",
            "schema": {
              "examples": [
                "cmb7q4w1s0003l804m2t6d9ka"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Disconnection confirmation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the stored OAuth connection was deleted.",
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "success"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/mcp-servers/connections/": {
      "get": {
        "operationId": "listMcpServerConnections",
        "summary": "List the caller’s OAuth connection statuses for all MCP servers",
        "tags": [
          "mcp-servers"
        ],
        "description": "Covers every MCP server of the caller’s company that is configured for OAuth, servers with other auth methods are omitted. Each entry matches the `GET /api/v1/mcp-servers/{mcpServerId}/connection/` response shape.",
        "responses": {
          "200": {
            "description": "The connection statuses",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "connections": {
                      "description": "Map of MCP server id to OAuth connection status details for every OAuth MCP server the caller can access. Each value matches the `GET /api/v1/mcp-servers/connection/?mcpServerId=…` response shape.",
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {
                        "type": "object",
                        "properties": {
                          "requiresOAuth": {
                            "description": "Whether the MCP server is configured to require a per-user OAuth connection.",
                            "type": "boolean"
                          },
                          "connected": {
                            "description": "Whether the caller currently has a stored OAuth connection. Always false when OAuth is not required.",
                            "type": "boolean"
                          },
                          "status": {
                            "description": "OAuth connection status: `not_connected`, `connected`, `expiring_soon` or `expired`. Null when the server does not require OAuth.",
                            "examples": [
                              "connected"
                            ],
                            "type": "string"
                          },
                          "tokenExpiresAt": {
                            "description": "ISO 8601 expiry time of the stored access token. Null when unknown or not connected.",
                            "examples": [
                              "2026-08-01T12:00:00.000Z"
                            ],
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "connectedAt": {
                            "description": "ISO 8601 time the OAuth connection was first created. Null when not connected.",
                            "examples": [
                              "2026-06-15T09:30:00.000Z"
                            ],
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "updatedAt": {
                            "description": "ISO 8601 time the stored connection was last refreshed. Null when not connected.",
                            "examples": [
                              "2026-07-01T18:45:00.000Z"
                            ],
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "transport": {
                            "description": "Transport the server is configured with: `sse` or `http`. Defaults to `sse`.",
                            "examples": [
                              "sse"
                            ],
                            "type": "string"
                          },
                          "authMethod": {
                            "description": "Authentication method configured on the server: `none`, `bearer` or `oauth`.",
                            "examples": [
                              "oauth"
                            ],
                            "type": "string"
                          }
                        },
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "connections"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/mcp-servers/test-connection/": {
      "post": {
        "operationId": "testMcpServerConnection",
        "summary": "Test connectivity to an MCP server (deprecated shape)",
        "tags": [
          "mcp-servers"
        ],
        "description": "Deprecated: use `POST /api/v1/mcp-servers/{mcpServerId}/test-connection/`, which addresses the server in the path instead of a required query parameter. This variant behaves identically. Opens a real client session against the server and lists its tools, so it exercises the configured transport, credentials and, for OAuth servers, the caller’s stored connection. Discovery failures answer `400` with the error message in the same response shape.",
        "deprecated": true,
        "parameters": [
          {
            "name": "mcpServerId",
            "in": "query",
            "required": true,
            "description": "Id of the MCP server.",
            "schema": {
              "examples": [
                "cmb7q4w1s0003l804m2t6d9ka"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The discovered tool names",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "Whether tool discovery against the server succeeded.",
                      "type": "boolean"
                    },
                    "toolCount": {
                      "description": "Number of tools the server exposes. Zero when discovery failed.",
                      "examples": [
                        5
                      ],
                      "type": "number"
                    },
                    "toolNames": {
                      "description": "Names of the tools discovered on the server. Empty when discovery failed.",
                      "examples": [
                        [
                          "search_issues",
                          "create_ticket"
                        ]
                      ],
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "error": {
                      "description": "Error message. Present only when discovery failed.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "success",
                    "toolCount",
                    "toolNames"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Tool discovery failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "Whether tool discovery against the server succeeded.",
                      "type": "boolean"
                    },
                    "toolCount": {
                      "description": "Number of tools the server exposes. Zero when discovery failed.",
                      "examples": [
                        5
                      ],
                      "type": "number"
                    },
                    "toolNames": {
                      "description": "Names of the tools discovered on the server. Empty when discovery failed.",
                      "examples": [
                        [
                          "search_issues",
                          "create_ticket"
                        ]
                      ],
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "error": {
                      "description": "Error message. Present only when discovery failed.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "success",
                    "toolCount",
                    "toolNames"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "MCP server not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/mcp-servers/oauth/authorize/": {
      "get": {
        "operationId": "authorizeMcpServerOAuth",
        "summary": "Start the OAuth authorization flow for an MCP server",
        "tags": [
          "mcp-servers"
        ],
        "description": "Discovers the MCP authorization server, registers a client when needed, builds a PKCE authorization request, and answers the provider authorization URL as JSON. The endpoint itself never issues a `302`. After consent the provider redirects back to `/api/oauth/mcp/callback`, which stores the tokens read by `GET /api/v1/mcp-servers/{mcpServerId}/connection/`.",
        "parameters": [
          {
            "name": "mcpServerId",
            "in": "query",
            "required": true,
            "description": "Id of the MCP server.",
            "schema": {
              "examples": [
                "cmb7q4w1s0003l804m2t6d9ka"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The provider authorization URL",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "authUrl": {
                      "description": "Provider authorization URL the client should redirect the user to.",
                      "examples": [
                        "https://auth.example.com/oauth/authorize?client_id=abc123&state=eyJraW5kIjoibWNwIn0"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "authUrl"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "MCP server is not configured for OAuth or its URL is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "MCP server not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "State-signing misconfiguration or provider error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/integrations/{id}/type/": {
      "get": {
        "operationId": "getIntegrationType",
        "summary": "Get the integration type of an integration",
        "tags": [
          "integrations"
        ],
        "description": "Resolves an integration of the caller’s company to its integration type and answers the type’s display name and icon URL. The chat UI uses it to render integration icons on tool chips.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id of the integration.",
            "schema": {
              "examples": [
                "cmb5t8n2p0007l804w3v1x6rq"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The integration type name and icon",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "description": "Name of the integration type.",
                      "examples": [
                        "Slack"
                      ],
                      "type": "string"
                    },
                    "icon": {
                      "description": "Icon URL of the integration type. Null when it has none.",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "name",
                    "icon"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Integration not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/usage/report/": {
      "get": {
        "operationId": "generateUsageReport",
        "summary": "Generate a PDF usage report",
        "tags": [
          "usage"
        ],
        "description": "Answers a PDF attachment. Accepts a `start`/`end` day range (or the legacy `year`/`month` pair), an optional CSV of application ids and a `mode` of `detailed` (default) or `summary`.",
        "parameters": [
          {
            "name": "start",
            "in": "query",
            "required": false,
            "description": "Range start day in `YYYY-MM-DD` format. When absent the report falls back to `year`/`month` or the current month.",
            "schema": {
              "examples": [
                "2026-06-01"
              ],
              "type": "string"
            }
          },
          {
            "name": "end",
            "in": "query",
            "required": false,
            "description": "Range end day in `YYYY-MM-DD` format. Defaults to today (UTC) when `start` is given.",
            "schema": {
              "examples": [
                "2026-06-30"
              ],
              "type": "string"
            }
          },
          {
            "name": "year",
            "in": "query",
            "required": false,
            "description": "Legacy year selector, used together with `month` when `start` is absent.",
            "schema": {
              "examples": [
                "2026"
              ],
              "type": "string"
            }
          },
          {
            "name": "month",
            "in": "query",
            "required": false,
            "description": "Legacy 0-based month selector, used together with `year` when `start` is absent.",
            "schema": {
              "examples": [
                "5"
              ],
              "type": "string"
            }
          },
          {
            "name": "applications",
            "in": "query",
            "required": false,
            "description": "Comma-separated application ids to filter by. Empty or absent means all applications.",
            "schema": {
              "examples": [
                "12,34"
              ],
              "type": "string"
            }
          },
          {
            "name": "mode",
            "in": "query",
            "required": false,
            "description": "Report mode. `detailed` (default) adds per-event detail tables, `summary` keeps only the totals.",
            "schema": {
              "examples": [
                "summary"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The usage report as an `application/pdf` attachment"
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/assistant/validate-attachments/": {
      "post": {
        "operationId": "validateAssistantAttachments",
        "summary": "Validate assistant file attachments",
        "tags": [
          "assistant"
        ],
        "description": "Checks each file’s MIME type and size before the client uploads it to an assistant chat. The accepted set is broader than the model’s native attachments: convertible and Docana-only types pass with their own size limits, and when code execution is enabled for the application any type is accepted. Validation never stores the files.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "files": {
                    "description": "Files to validate. When omitted the endpoint answers an empty result list.",
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "description": "File name.",
                          "examples": [
                            "report.pdf"
                          ],
                          "type": "string"
                        },
                        "mimeType": {
                          "description": "MIME type of the file.",
                          "examples": [
                            "application/pdf"
                          ],
                          "type": "string"
                        },
                        "size": {
                          "description": "File size in bytes.",
                          "examples": [
                            1048576
                          ],
                          "type": "number"
                        }
                      }
                    }
                  },
                  "applicationId": {
                    "description": "Id of the application the assistant chat belongs to. Used to resolve per-application feature flags such as code execution.",
                    "examples": [
                      42
                    ],
                    "type": "number"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Per-file validation results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "description": "One validation result per submitted file, in the same order.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "description": "File name as submitted. `file` when it was missing.",
                            "examples": [
                              "report.pdf"
                            ],
                            "type": "string"
                          },
                          "mimeType": {
                            "description": "MIME type as submitted. Empty when it was missing.",
                            "examples": [
                              "application/pdf"
                            ],
                            "type": "string"
                          },
                          "size": {
                            "description": "File size in bytes as submitted. Zero when it was missing.",
                            "examples": [
                              1048576
                            ],
                            "type": "number"
                          },
                          "ok": {
                            "description": "Whether the file passed validation.",
                            "type": "boolean"
                          },
                          "code": {
                            "description": "Failure code: `assistant-unsupported-mime-type` or `assistant-file-too-large`. Absent when `ok` is true.",
                            "examples": [
                              "assistant-file-too-large"
                            ],
                            "type": "string"
                          },
                          "maxSize": {
                            "description": "Maximum allowed size in bytes. Present only with the `assistant-file-too-large` code.",
                            "examples": [
                              104857600
                            ],
                            "type": "number"
                          }
                        },
                        "required": [
                          "name",
                          "mimeType",
                          "size",
                          "ok"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "results"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/ai/tools/common/": {
      "get": {
        "operationId": "listCommonAiTools",
        "summary": "List the common AI tools available to the caller",
        "tags": [
          "ai-tools"
        ],
        "description": "Reads tool metadata only, it never starts a sandbox or browser session. Pass `includeSchema=true` to add each tool’s input parameter schema, and `applicationId` to include application-gated toolsets such as code execution and Browserbase browsing. Pass `responseShape=toolsets` for only the lightweight gate-status report. `toolsetId` limits that report in either response shape; it does not filter full-response `items`. Check a non-available toolset’s `reason` to see what would enable it.",
        "parameters": [
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application to scope tool availability to. Unparseable values are ignored.",
            "schema": {
              "examples": [
                42
              ],
              "type": "number"
            }
          },
          {
            "name": "includeSchema",
            "in": "query",
            "required": false,
            "description": "Pass the literal `true` to include each tool input parameter schema. Any other value means false.",
            "schema": {}
          },
          {
            "name": "responseShape",
            "in": "query",
            "required": false,
            "description": "Response detail level. `full` returns the tool catalog and optional input schemas; `toolsets` returns only the lightweight availability report. Defaults to `full` when omitted.",
            "schema": {
              "type": "string",
              "enum": [
                "full",
                "toolsets"
              ]
            }
          },
          {
            "name": "toolsetId",
            "in": "query",
            "required": false,
            "description": "Limits the toolsets report to one toolset in either response shape. In the full response, it does not filter `items`.",
            "schema": {
              "type": "string",
              "enum": [
                "codeExecution",
                "browsing"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The available tools",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "items": {
                          "description": "Tools available to the caller.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "description": "Tool name.",
                                "examples": [
                                  "similaritySearch"
                                ],
                                "type": "string"
                              },
                              "description": {
                                "description": "Human-readable description of what the tool does.",
                                "type": "string"
                              },
                              "inputSchema": {
                                "description": "JSON Schema of the tool input parameters. Present only when `includeSchema=true` was passed.",
                                "type": "object",
                                "propertyNames": {
                                  "type": "string"
                                },
                                "additionalProperties": {}
                              }
                            },
                            "required": [
                              "name",
                              "description"
                            ],
                            "additionalProperties": false
                          }
                        },
                        "toolsets": {
                          "description": "Gate status of the application-gated toolsets. Tools of non-available toolsets are omitted from `items`, so this is the only way to tell \"disabled for me\" apart from \"does not exist\".",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "description": "The gated toolset this entry reports on.",
                                "type": "string",
                                "enum": [
                                  "codeExecution",
                                  "browsing"
                                ]
                              },
                              "status": {
                                "description": "`available`: its tools are in `items`. `disabled`: turned off for this application/company (or not evaluable without `applicationId`). `unconfigured`: enabled but the deployment lacks the credentials it needs, so its tools would fail at runtime.",
                                "type": "string",
                                "enum": [
                                  "available",
                                  "disabled",
                                  "unconfigured"
                                ]
                              },
                              "reason": {
                                "description": "Why the toolset is not available, when it is not.",
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "status"
                            ],
                            "additionalProperties": false
                          }
                        }
                      },
                      "required": [
                        "items",
                        "toolsets"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "toolsets": {
                          "description": "Gate status of the application-gated toolsets. Tools of non-available toolsets are omitted from `items`, so this is the only way to tell \"disabled for me\" apart from \"does not exist\".",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "description": "The gated toolset this entry reports on.",
                                "type": "string",
                                "enum": [
                                  "codeExecution",
                                  "browsing"
                                ]
                              },
                              "status": {
                                "description": "`available`: its tools are in `items`. `disabled`: turned off for this application/company (or not evaluable without `applicationId`). `unconfigured`: enabled but the deployment lacks the credentials it needs, so its tools would fail at runtime.",
                                "type": "string",
                                "enum": [
                                  "available",
                                  "disabled",
                                  "unconfigured"
                                ]
                              },
                              "reason": {
                                "description": "Why the toolset is not available, when it is not.",
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "status"
                            ],
                            "additionalProperties": false
                          }
                        }
                      },
                      "required": [
                        "toolsets"
                      ],
                      "additionalProperties": false
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Tool listing failure",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/skills/": {
      "get": {
        "operationId": "listSkills",
        "summary": "List the skills the caller can manage",
        "tags": [
          "skills"
        ],
        "description": "Answers GLOBAL skills read-only, the company’s COMPANY skills and, when `applicationId` is supplied and accessible, that application’s APPLICATION skills. Answers `404` when the skills feature flag is off at the requested scope, so the surface looks nonexistent outside the rollout.",
        "parameters": [
          {
            "name": "applicationId",
            "in": "query",
            "required": false,
            "description": "Id of the application whose APPLICATION-scoped skills to include in the listing.",
            "schema": {
              "examples": [
                42
              ],
              "type": "integer",
              "minimum": -9007199254740991,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The visible skills catalogue",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the request succeeded.",
                      "type": "boolean"
                    },
                    "skills": {
                      "description": "Skills visible to the caller, ordered by scope then name. GLOBAL skills are included read-only.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "Id of the skill.",
                            "examples": [
                              "cmb3f7d9r0002l804u5p2k1mw"
                            ],
                            "type": "string"
                          },
                          "name": {
                            "description": "Skill name, from the SKILL.md frontmatter.",
                            "examples": [
                              "pdf-form-filler"
                            ],
                            "type": "string"
                          },
                          "description": {
                            "description": "Short description of what the skill does, from the SKILL.md frontmatter.",
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "enabled": {
                            "description": "Whether the skill is enabled and available to the assistant.",
                            "type": "boolean"
                          },
                          "scope": {
                            "description": "Visibility scope: `GLOBAL`, `COMPANY` or `APPLICATION`.",
                            "examples": [
                              "COMPANY"
                            ],
                            "type": "string"
                          },
                          "companyId": {
                            "description": "Id of the owning company. Null for GLOBAL skills.",
                            "examples": [
                              17
                            ],
                            "anyOf": [
                              {
                                "type": "number"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "applicationId": {
                            "description": "Id of the owning application. Null for GLOBAL and COMPANY skills.",
                            "examples": [
                              42
                            ],
                            "anyOf": [
                              {
                                "type": "number"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "description",
                          "enabled",
                          "scope",
                          "companyId",
                          "applicationId"
                        ],
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "success",
                    "skills"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the requested application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Skills feature not enabled at the requested scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "uploadSkill",
        "summary": "Upload a skill from a ZIP archive",
        "tags": [
          "skills"
        ],
        "description": "Accepts `multipart/form-data` with a ZIP `file`, a `scope` of COMPANY or APPLICATION, and an `applicationId` when scope is APPLICATION. Replaces any existing skill with the same name in the same scope.",
        "requestBody": {
          "required": true,
          "description": "Multipart form with the skill ZIP and the scope to create it at.",
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "description": "The skill ZIP archive, sent as a binary file part rather than a plain string. The archive must contain a SKILL.md, at the root or inside a single folder, whose frontmatter carries the skill name and description.",
                    "type": "string"
                  },
                  "scope": {
                    "description": "Visibility scope to create the skill at. Matched case-insensitively.",
                    "examples": [
                      "COMPANY"
                    ],
                    "type": "string",
                    "enum": [
                      "COMPANY",
                      "APPLICATION"
                    ]
                  },
                  "applicationId": {
                    "description": "Id of the target application, as a numeric form field. Required when `scope` is APPLICATION.",
                    "examples": [
                      "42"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "file",
                  "scope"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The created or updated skill",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the request succeeded.",
                      "type": "boolean"
                    },
                    "updated": {
                      "description": "True when an existing skill with the same name and scope was replaced instead of created.",
                      "type": "boolean"
                    },
                    "skill": {
                      "description": "The created or updated skill. Also carries the `files` manifest.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "Id of the skill.",
                          "examples": [
                            "cmb3f7d9r0002l804u5p2k1mw"
                          ],
                          "type": "string"
                        },
                        "name": {
                          "description": "Skill name, from the SKILL.md frontmatter.",
                          "examples": [
                            "pdf-form-filler"
                          ],
                          "type": "string"
                        },
                        "description": {
                          "description": "Short description of what the skill does, from the SKILL.md frontmatter.",
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "scope": {
                          "description": "Visibility scope the skill was created at: `COMPANY` or `APPLICATION`.",
                          "examples": [
                            "COMPANY"
                          ],
                          "type": "string"
                        },
                        "companyId": {
                          "description": "Id of the owning company.",
                          "examples": [
                            17
                          ],
                          "type": "number"
                        },
                        "applicationId": {
                          "description": "Id of the owning application. Null for COMPANY skills.",
                          "examples": [
                            42
                          ],
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "description",
                        "scope",
                        "companyId",
                        "applicationId"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "success",
                    "updated",
                    "skill"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Missing/invalid file, scope or applicationId",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Caller lacks admin rights at the chosen scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Skills feature not enabled at the requested scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/skills/{id}/": {
      "get": {
        "operationId": "getSkill",
        "summary": "Get a skill by id",
        "tags": [
          "skills"
        ],
        "description": "Only COMPANY and APPLICATION skills are readable here, GLOBAL skills answer `404`. The detail payload adds `instructions`, `gcsPath` and the file manifest on top of the `GET /api/v1/skills/` item shape.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id of the skill.",
            "schema": {
              "examples": [
                "cmb3f7d9r0002l804u5p2k1mw"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The skill",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the request succeeded.",
                      "type": "boolean"
                    },
                    "skill": {
                      "description": "The skill. Also carries `instructions`, `gcsPath`, the `files` manifest and timestamps.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "Id of the skill.",
                          "examples": [
                            "cmb3f7d9r0002l804u5p2k1mw"
                          ],
                          "type": "string"
                        },
                        "name": {
                          "description": "Skill name, from the SKILL.md frontmatter.",
                          "examples": [
                            "pdf-form-filler"
                          ],
                          "type": "string"
                        },
                        "description": {
                          "description": "Short description of what the skill does, from the SKILL.md frontmatter.",
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "enabled": {
                          "description": "Whether the skill is enabled and available to the assistant.",
                          "type": "boolean"
                        },
                        "scope": {
                          "description": "Visibility scope: `GLOBAL`, `COMPANY` or `APPLICATION`.",
                          "examples": [
                            "COMPANY"
                          ],
                          "type": "string"
                        },
                        "companyId": {
                          "description": "Id of the owning company. Null for GLOBAL skills.",
                          "examples": [
                            17
                          ],
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "applicationId": {
                          "description": "Id of the owning application. Null for GLOBAL and COMPANY skills.",
                          "examples": [
                            42
                          ],
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "description",
                        "enabled",
                        "scope",
                        "companyId",
                        "applicationId"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "success",
                    "skill"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No read access to the skill",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Skill not found or feature disabled",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateSkill",
        "summary": "Enable or disable a skill",
        "tags": [
          "skills"
        ],
        "description": "Only the `enabled` flag can be changed through this endpoint. Requires company-admin rights for COMPANY skills, and application-admin or company-admin rights for APPLICATION skills.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id of the skill.",
            "schema": {
              "examples": [
                "cmb3f7d9r0002l804u5p2k1mw"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "description": "New enabled state for the skill.",
                    "examples": [
                      true
                    ],
                    "type": "boolean"
                  }
                },
                "required": [
                  "enabled"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The toggled skill",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the request succeeded.",
                      "type": "boolean"
                    },
                    "skill": {
                      "description": "The skill after the toggle.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "Id of the skill.",
                          "examples": [
                            "cmb3f7d9r0002l804u5p2k1mw"
                          ],
                          "type": "string"
                        },
                        "name": {
                          "description": "Skill name.",
                          "examples": [
                            "pdf-form-filler"
                          ],
                          "type": "string"
                        },
                        "description": {
                          "description": "Short description of what the skill does.",
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "enabled": {
                          "description": "The enabled state after the update.",
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "description",
                        "enabled"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "skill"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Caller lacks admin rights at the skill’s scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Skill not found or feature disabled",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteSkill",
        "summary": "Delete a skill",
        "tags": [
          "skills"
        ],
        "description": "Deletes the skill row and its files in storage. File cleanup failures are logged but do not block the deletion. Requires the same admin rights as `PATCH /api/v1/skills/{id}/`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id of the skill.",
            "schema": {
              "examples": [
                "cmb3f7d9r0002l804u5p2k1mw"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deletion confirmation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the skill and its stored files were deleted.",
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "success"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Caller lacks admin rights at the skill’s scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Skill not found or feature disabled",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/skills/builder/": {
      "post": {
        "operationId": "runSkillBuilder",
        "summary": "Chat with the skill builder (streaming)",
        "tags": [
          "skills"
        ],
        "description": "Streams an AI SDK UI-message response. Accepts a chat payload `{ messages, data }` where `data` carries the draft file tree, name, description and authoring scope.",
        "x-docana-streaming": true,
        "requestBody": {
          "required": true,
          "description": "AI SDK chat payload with the conversation and the client-owned draft context. Parsed leniently by the handler.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "messages": {
                    "description": "The conversation so far, oldest first. Defaults to an empty conversation when omitted.",
                    "type": "array",
                    "items": {
                      "description": "An AI SDK UI message. File uploads may also arrive as a legacy `experimental_attachments` array.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "Client-generated message id.",
                          "examples": [
                            "msg_a1b2c3d4"
                          ],
                          "type": "string"
                        },
                        "role": {
                          "description": "Message author: `user`, `assistant` or `system`.",
                          "examples": [
                            "user"
                          ],
                          "type": "string"
                        },
                        "parts": {
                          "description": "AI SDK UI message parts, typically one `{ type: \"text\", text }` part per user turn.",
                          "examples": [
                            [
                              {
                                "type": "text",
                                "text": "Create a skill that fills PDF forms."
                              }
                            ]
                          ],
                          "type": "array",
                          "items": {}
                        }
                      },
                      "required": [
                        "role"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "data": {
                    "description": "Draft context for this turn. The draft lives in the browser until the user creates the skill.",
                    "type": "object",
                    "properties": {
                      "scope": {
                        "description": "Authoring scope. GLOBAL is super-admin only. Any other value, or omitting the field, means COMPANY.",
                        "examples": [
                          "COMPANY"
                        ],
                        "type": "string",
                        "enum": [
                          "GLOBAL",
                          "COMPANY"
                        ]
                      },
                      "files": {
                        "description": "The client-owned draft file tree. Sent in full each turn so the builder always has context.",
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "path": {
                              "description": "File path relative to the skill root.",
                              "examples": [
                                "SKILL.md"
                              ],
                              "type": "string"
                            },
                            "content": {
                              "description": "Full UTF-8 content of the file.",
                              "examples": [
                                "---\nname: pdf-form-filler\ndescription: Fills PDF forms from JSON data.\n---\n\nUse the fill_form.py script to write values into AcroForm fields."
                              ],
                              "type": "string"
                            }
                          },
                          "required": [
                            "path",
                            "content"
                          ]
                        }
                      },
                      "name": {
                        "description": "Current draft skill name.",
                        "examples": [
                          "pdf-form-filler"
                        ],
                        "type": "string"
                      },
                      "description": {
                        "description": "Current draft skill description.",
                        "examples": [
                          "Fills PDF forms from JSON data."
                        ],
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A UI-message event stream with the builder’s reply and file operations"
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Caller lacks authoring rights at the requested scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Skills feature not enabled for the company",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/skills/install-from-registry/": {
      "post": {
        "operationId": "installSkillFromRegistry",
        "summary": "Install skills from the skills.sh registry",
        "tags": [
          "skills"
        ],
        "description": "Downloads the GitHub repository behind `source` as a zipball, extracts every `SKILL.md` folder (optionally filtered by `skill`) and creates or updates the skills at the chosen scope, replacing same-name skills. Only github.com sources are supported. Use `GET /api/v1/skills/registry/search/` or `GET /api/v1/skills/registry/popular/` to find sources.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "source": {
                    "description": "Skill source: an `owner/repo` shorthand or a GitHub URL, optionally with `/tree/<ref>/<subpath>`. Only github.com sources are supported.",
                    "examples": [
                      "anthropics/skills"
                    ],
                    "type": "string"
                  },
                  "ref": {
                    "description": "Git ref override, a branch, tag or commit SHA. Defaults to the repository default branch.",
                    "examples": [
                      "main"
                    ],
                    "type": "string"
                  },
                  "skill": {
                    "description": "Skill name filter for repositories that contain several skills.",
                    "examples": [
                      "xlsx"
                    ],
                    "type": "string"
                  },
                  "scope": {
                    "description": "Install scope: `COMPANY` or `APPLICATION`. Matched case-insensitively.",
                    "type": "string"
                  },
                  "applicationId": {
                    "description": "Id of the target application, as a number or a numeric string. Required when `scope` is APPLICATION.",
                    "examples": [
                      42
                    ],
                    "anyOf": [
                      {
                        "type": "number"
                      },
                      {
                        "type": "string"
                      }
                    ]
                  }
                },
                "required": [
                  "source",
                  "scope"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The install result",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Install summary. Also carries the resolved `source` and `sourceRef`, an `installed` list of created or updated skills, and a `skipped` list with per-folder reasons.",
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the install completed.",
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "success"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "Invalid source, scope or applicationId",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Caller lacks admin rights at the chosen scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Skills feature not enabled at the requested scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/skills/registry/popular/": {
      "get": {
        "operationId": "listPopularRegistrySkills",
        "summary": "List popular skills from the skills.sh registry",
        "tags": [
          "skills"
        ],
        "description": "`limit` is clamped to 1..50 (default 12); invalid `sortBy` values fall back to `installs`.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of skills to return, clamped to 1..50.",
            "schema": {
              "examples": [
                12
              ]
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Leaderboard ordering. `installs` uses the skills.sh install count, `stars` and `recent` use GitHub stargazers and last-push time of the source repository.",
            "schema": {
              "examples": [
                "stars"
              ],
              "default": "installs",
              "type": "string",
              "enum": [
                "installs",
                "stars",
                "recent"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The registry leaderboard",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the request succeeded.",
                      "type": "boolean"
                    },
                    "sortBy": {
                      "description": "The ordering that was applied.",
                      "examples": [
                        "installs"
                      ],
                      "type": "string"
                    },
                    "results": {
                      "description": "Leaderboard entries. Each entry carries the skills.sh id, name, `owner/repo` install source, install count and GitHub repository stats.",
                      "type": "array",
                      "items": {}
                    }
                  },
                  "required": [
                    "success",
                    "sortBy",
                    "results"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/skills/registry/search/": {
      "get": {
        "operationId": "searchSkillRegistry",
        "summary": "Search the skills.sh registry",
        "tags": [
          "skills"
        ],
        "description": "`limit` is clamped to 1..50 (default 10).",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Search query. An empty value answers an empty result list.",
            "schema": {
              "examples": [
                "spreadsheet"
              ],
              "default": "",
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of results to return, clamped to 1..50.",
            "schema": {
              "examples": [
                10
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The registry search results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the request succeeded.",
                      "type": "boolean"
                    },
                    "query": {
                      "description": "The query that was searched.",
                      "examples": [
                        "spreadsheet"
                      ],
                      "type": "string"
                    },
                    "results": {
                      "description": "Matching registry entries, most-installed first. Each entry carries the skills.sh id, name, `owner/repo` install source, skill folder name and install count.",
                      "type": "array",
                      "items": {}
                    }
                  },
                  "required": [
                    "success",
                    "query",
                    "results"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/threads/": {
      "post": {
        "operationId": "createThread",
        "summary": "Create a thread",
        "tags": [
          "threads"
        ],
        "description": "Supports the `Idempotency-Key` header: retrying with the same key and body replays the original thread (`Idempotency-Replay: true`); reusing a key with a different body answers 409.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "applicationId": {
                    "description": "Id of the application the thread belongs to.",
                    "examples": [
                      7
                    ],
                    "type": "number"
                  },
                  "type": {
                    "description": "Type of the thread. Defaults to `ASSISTANT`.",
                    "examples": [
                      "ASSISTANT"
                    ],
                    "default": "ASSISTANT",
                    "type": "string",
                    "enum": [
                      "DOCUMENT_INSIGHTS",
                      "ASSISTANT",
                      "WHATSAPP",
                      "WHATSAPP_BUSINESS",
                      "SLACK",
                      "TEAMS",
                      "WIDGET",
                      "SEARCH",
                      "OTHER",
                      "AGENT_BUILDER",
                      "AGENT",
                      "AGENT_SANDBOX",
                      "AGENT_EVAL",
                      "AGENT_ROUTINE",
                      "DOCUMENT_BUILDER"
                    ]
                  },
                  "description": {
                    "description": "Description shown in thread lists.",
                    "examples": [
                      "Order status check-in with Acme Corp"
                    ],
                    "type": "string"
                  },
                  "isPrivate": {
                    "description": "Whether the thread is private to its owner.",
                    "examples": [
                      false
                    ],
                    "type": "boolean"
                  },
                  "whatsAppUser": {
                    "description": "WhatsApp identity that owns the thread instead of the authenticated caller. Requires the application ADMIN role. Must include `phoneNumber` or `businessScopedUserId`.",
                    "type": "object",
                    "properties": {
                      "phoneNumber": {
                        "description": "Phone number of the WhatsApp user.",
                        "examples": [
                          "+14155552671"
                        ],
                        "type": "string"
                      },
                      "businessScopedUserId": {
                        "description": "Business-scoped user id (BSUID) that WhatsApp assigns to the user for this business.",
                        "examples": [
                          "549132876543210"
                        ],
                        "type": "string"
                      },
                      "parentBusinessScopedUserId": {
                        "description": "Business-scoped user id assigned under the parent business, when the account is part of a portfolio.",
                        "examples": [
                          "549132876543211"
                        ],
                        "type": "string"
                      },
                      "username": {
                        "description": "WhatsApp username of the user, stored on the resolved identity.",
                        "examples": [
                          "ana.souza"
                        ],
                        "type": "string"
                      },
                      "profileName": {
                        "description": "WhatsApp profile name, used as the display name when a new user is created.",
                        "examples": [
                          "Ana Souza"
                        ],
                        "type": "string"
                      }
                    }
                  }
                },
                "required": [
                  "applicationId"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created thread",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "Id of the thread.",
                      "examples": [
                        "cm4xk2p9d0001abcd12345678"
                      ],
                      "type": "string"
                    },
                    "applicationId": {
                      "description": "Id of the application the thread belongs to, or null.",
                      "examples": [
                        7
                      ],
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "companyId": {
                      "description": "Id of the company that owns the thread.",
                      "type": "number"
                    },
                    "userId": {
                      "description": "Id of the user who owns the thread.",
                      "type": "number"
                    },
                    "type": {
                      "description": "Type of the thread.",
                      "examples": [
                        "ASSISTANT"
                      ],
                      "type": "string"
                    },
                    "description": {
                      "description": "Description shown in thread lists, or null.",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "isPrivate": {
                      "description": "Whether the thread is private to its owner, or null.",
                      "anyOf": [
                        {
                          "type": "boolean"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "createdAt": {
                      "description": "When the thread was created, as an ISO 8601 timestamp.",
                      "examples": [
                        "2026-01-15T09:30:00.000Z"
                      ],
                      "type": "string"
                    },
                    "updatedAt": {
                      "description": "When the thread was last updated, as an ISO 8601 timestamp.",
                      "examples": [
                        "2026-01-15T10:05:00.000Z"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "applicationId",
                    "companyId",
                    "userId",
                    "type",
                    "description",
                    "isPrivate",
                    "createdAt",
                    "updatedAt"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or thread creation failure",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key conflict or in-progress request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/": {
      "get": {
        "operationId": "getThread",
        "summary": "Get a thread",
        "tags": [
          "threads"
        ],
        "description": "Answers the same shape `POST /api/v1/threads/` returns. The lookup is scoped to the caller’s company and, when the thread belongs to an application, requires access to that application.",
        "parameters": [
          {
            "name": "threadId",
            "in": "path",
            "required": true,
            "description": "Id of the thread.",
            "schema": {
              "examples": [
                "cm4xk2p9d0001abcd12345678"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The thread",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "Id of the thread.",
                      "examples": [
                        "cm4xk2p9d0001abcd12345678"
                      ],
                      "type": "string"
                    },
                    "applicationId": {
                      "description": "Id of the application the thread belongs to, or null.",
                      "examples": [
                        7
                      ],
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "companyId": {
                      "description": "Id of the company that owns the thread.",
                      "type": "number"
                    },
                    "userId": {
                      "description": "Id of the user who owns the thread.",
                      "type": "number"
                    },
                    "type": {
                      "description": "Type of the thread.",
                      "examples": [
                        "ASSISTANT"
                      ],
                      "type": "string"
                    },
                    "description": {
                      "description": "Description shown in thread lists, or null.",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "isPrivate": {
                      "description": "Whether the thread is private to its owner, or null.",
                      "anyOf": [
                        {
                          "type": "boolean"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "createdAt": {
                      "description": "When the thread was created, as an ISO 8601 timestamp.",
                      "examples": [
                        "2026-01-15T09:30:00.000Z"
                      ],
                      "type": "string"
                    },
                    "updatedAt": {
                      "description": "When the thread was last updated, as an ISO 8601 timestamp.",
                      "examples": [
                        "2026-01-15T10:05:00.000Z"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "applicationId",
                    "companyId",
                    "userId",
                    "type",
                    "description",
                    "isPrivate",
                    "createdAt",
                    "updatedAt"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No access to the thread’s application",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Thread not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/messages/": {
      "get": {
        "operationId": "listThreadMessages",
        "summary": "List messages of a thread",
        "tags": [
          "threads"
        ],
        "description": "`take` is clamped to 50. `cursor` is a message id; only messages older than it are returned.",
        "parameters": [
          {
            "name": "threadId",
            "in": "path",
            "required": true,
            "description": "Id of the thread.",
            "schema": {
              "examples": [
                "cm4xk2p9d0001abcd12345678"
              ],
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "take",
            "in": "query",
            "required": false,
            "description": "Number of messages per page, clamped to 50. Defaults to 20.",
            "schema": {
              "examples": [
                20
              ]
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Message id to page backwards from. Only messages created before it are returned.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "One page of messages, oldest first",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "messages": {
                      "description": "One page of messages ordered oldest first.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "Id of the message.",
                            "type": "string"
                          },
                          "role": {
                            "description": "Author role of the message: `USER`, `ASSISTANT`, `SYSTEM`, or `TOOL`.",
                            "examples": [
                              "USER"
                            ],
                            "type": "string"
                          },
                          "content": {
                            "description": "Content of the message: a string, or an array of parts. Attachment file parts carry the `documentId` of the ingested attachment, a `url` pointing at `GET /api/v1/documents/{documentId}/download/` (authenticated), and a `viewUrl` — a time-limited pre-authorized link to the same bytes that can be fetched, rendered or attached without platform credentials (it expires after a few hours; re-fetch the message for a fresh one). Document URLs embedded in tool results (for example a search result’s `downloadUrl`) carry the same time-limited `vid` token and are directly fetchable too. The transcription or extracted text of that attachment is available at `GET /api/v1/documents/{documentId}/content/`."
                          }
                        },
                        "required": [
                          "id",
                          "role",
                          "content"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "hasMore": {
                      "description": "True when older messages exist beyond this page.",
                      "type": "boolean"
                    },
                    "totalCount": {
                      "description": "Total number of messages in the thread, excluding system and tool messages.",
                      "type": "number"
                    }
                  },
                  "required": [
                    "messages",
                    "hasMore",
                    "totalCount"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Thread not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/archive/": {
      "post": {
        "operationId": "archiveThread",
        "summary": "Archive a thread",
        "tags": [
          "threads"
        ],
        "description": "Accepts an optional JSON body `{ agentId?, summarize? }`: `summarize=false` archives without a summary, `agentId` selects the insights agent, and no body lets the thread metadata decide. Supports the `Idempotency-Key` header: a retry with the same key and body replays the stored response instead of re-triggering the summary.",
        "parameters": [
          {
            "name": "threadId",
            "in": "path",
            "required": true,
            "description": "Id of the thread.",
            "schema": {
              "examples": [
                "cm4xk2p9d0001abcd12345678"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Optional archive options. An empty body archives with the summary behavior the thread metadata decides.",
          "content": {
            "application/json": {
              "schema": {
                "description": "Optional archive options. Without a body the thread metadata decides whether a summary is generated.",
                "type": "object",
                "properties": {
                  "agentId": {
                    "description": "Id of the agent whose insights configuration drives the archive summary. The agent must have insights enabled.",
                    "examples": [
                      "cmc3k1x9d0001l608r2vhq7e2"
                    ],
                    "type": "string",
                    "minLength": 1
                  },
                  "summarize": {
                    "description": "Set to false to archive without generating a summary. When omitted, the agent recorded in the thread metadata decides.",
                    "examples": [
                      false
                    ],
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The archived thread",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the request succeeded.",
                      "type": "boolean"
                    },
                    "thread": {
                      "description": "The archived thread.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "Id of the thread.",
                          "examples": [
                            "cm4xk2p9d0001abcd12345678"
                          ],
                          "type": "string"
                        },
                        "applicationId": {
                          "description": "Id of the application the thread belongs to, or null.",
                          "examples": [
                            7
                          ],
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "companyId": {
                          "description": "Id of the company that owns the thread.",
                          "type": "number"
                        },
                        "userId": {
                          "description": "Id of the user who owns the thread.",
                          "type": "number"
                        },
                        "type": {
                          "description": "Type of the thread.",
                          "examples": [
                            "ASSISTANT"
                          ],
                          "type": "string"
                        },
                        "description": {
                          "description": "Description shown in thread lists, or null.",
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "isPrivate": {
                          "description": "Whether the thread is private to its owner, or null.",
                          "anyOf": [
                            {
                              "type": "boolean"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "createdAt": {
                          "description": "When the thread was created, as an ISO 8601 timestamp.",
                          "examples": [
                            "2026-01-15T09:30:00.000Z"
                          ],
                          "type": "string"
                        },
                        "updatedAt": {
                          "description": "When the thread was last updated, as an ISO 8601 timestamp.",
                          "examples": [
                            "2026-01-15T10:05:00.000Z"
                          ],
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "applicationId",
                        "companyId",
                        "userId",
                        "type",
                        "description",
                        "isPrivate",
                        "createdAt",
                        "updatedAt"
                      ],
                      "additionalProperties": {}
                    },
                    "alreadyArchived": {
                      "description": "Present and true when the thread was already archived and no archival write happened.",
                      "type": "boolean"
                    },
                    "summaryRequested": {
                      "description": "Whether an insights summary extraction was scheduled as part of this request.",
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "success",
                    "thread"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Malformed body or unusable agent",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Thread not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key conflict or in-progress request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/latest-insights/": {
      "get": {
        "operationId": "getThreadLatestInsights",
        "summary": "Get the latest insights snapshot of a thread",
        "tags": [
          "threads"
        ],
        "description": "Snapshots are produced by insight extraction, which runs after agent turns or when a thread is archived with an insights-enabled agent (see `POST /api/v1/threads/{threadId}/archive/`). Answers `null` with status 200, not 404, when the thread exists but has no snapshot yet.",
        "parameters": [
          {
            "name": "threadId",
            "in": "path",
            "required": true,
            "description": "Id of the thread.",
            "schema": {
              "examples": [
                "cm4xk2p9d0001abcd12345678"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The latest snapshot, or null when none exists",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "Id of the insights snapshot.",
                          "type": "string"
                        },
                        "summary": {
                          "description": "LLM-generated summary of the conversation at extraction time, or null when none was produced.",
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "insights": {
                          "description": "Structured data points extracted from the conversation, each with `id`, `name`, and a stringified `value`.",
                          "type": "array",
                          "items": {}
                        },
                        "score": {
                          "description": "Quality score of the extraction between 0 and 1, or null when not evaluated.",
                          "examples": [
                            0.85
                          ],
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "reason": {
                          "description": "Free-form reasoning behind the score, or null.",
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "extractedAt": {
                          "description": "When the extraction completed, as an ISO 8601 timestamp.",
                          "examples": [
                            "2026-01-15T10:05:00.000Z"
                          ],
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "summary",
                        "insights",
                        "score",
                        "reason",
                        "extractedAt"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "null"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path failed validation. See `validationErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Thread not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/users/": {
      "get": {
        "operationId": "listUsers",
        "summary": "List the users of the caller’s company",
        "tags": [
          "users"
        ],
        "description": "Answers the full company roster from a short-lived cache, so very recent user changes may lag briefly. Use `GET /api/v1/users/me/` for the caller’s own record.",
        "responses": {
          "200": {
            "description": "All users in the authenticated user’s company",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "description": "Id of the user.",
                        "examples": [
                          123
                        ],
                        "type": "number"
                      },
                      "email": {
                        "description": "Email address of the user.",
                        "examples": [
                          "ana.souza@acme.com"
                        ],
                        "type": "string"
                      },
                      "firstName": {
                        "description": "First name of the user. Null when not set.",
                        "examples": [
                          "Ana"
                        ],
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "lastName": {
                        "description": "Last name of the user. Null when not set.",
                        "examples": [
                          "Souza"
                        ],
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "companyId": {
                        "description": "Id of the company the user belongs to.",
                        "examples": [
                          17
                        ],
                        "type": "number"
                      },
                      "role": {
                        "description": "Company-level role: `ADMIN`, `USER` or `GUEST`.",
                        "examples": [
                          "USER"
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "id",
                      "email",
                      "firstName",
                      "lastName",
                      "companyId",
                      "role"
                    ],
                    "additionalProperties": {}
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/users/me/": {
      "get": {
        "operationId": "getCurrentUser",
        "summary": "Get the authenticated user",
        "tags": [
          "users"
        ],
        "description": "Returns the caller in the same item shape as the `GET /api/users/` list.",
        "responses": {
          "200": {
            "description": "The authenticated user",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "Id of the user.",
                      "examples": [
                        123
                      ],
                      "type": "number"
                    },
                    "email": {
                      "description": "Email address of the user.",
                      "examples": [
                        "ana.souza@acme.com"
                      ],
                      "type": "string"
                    },
                    "firstName": {
                      "description": "First name of the user. Null when not set.",
                      "examples": [
                        "Ana"
                      ],
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "lastName": {
                      "description": "Last name of the user. Null when not set.",
                      "examples": [
                        "Souza"
                      ],
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "companyId": {
                      "description": "Id of the company the user belongs to.",
                      "examples": [
                        17
                      ],
                      "type": "number"
                    },
                    "role": {
                      "description": "Company-level role: `ADMIN`, `USER` or `GUEST`.",
                      "examples": [
                        "USER"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "email",
                    "firstName",
                    "lastName",
                    "companyId",
                    "role"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/users/me/metadata/": {
      "get": {
        "operationId": "getUserMetadata",
        "summary": "Get the authenticated user’s metadata",
        "tags": [
          "users"
        ],
        "description": "Reads the metadata map fresh from the database rather than the session cache. Keys are written via `POST /api/v1/users/me/metadata/`.",
        "responses": {
          "200": {
            "description": "The user’s metadata key-value map",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Arbitrary key-value metadata stored on the user. Keys are written via `POST /api/v1/users/me/metadata/`.",
                  "type": "object",
                  "propertyNames": {
                    "type": "string"
                  },
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "updateUserMetadata",
        "summary": "Merge a key-value pair into the authenticated user’s metadata",
        "tags": [
          "users"
        ],
        "description": "Merges a single key-value pair into the existing metadata, other keys are preserved. Also invalidates the caller’s session verification cache so the new metadata is visible on the next request.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "key": {
                    "description": "Metadata key to set.",
                    "examples": [
                      "onboardingDismissed"
                    ],
                    "type": "string",
                    "minLength": 1
                  },
                  "value": {
                    "description": "Value to store under the key. Any JSON value.",
                    "examples": [
                      true
                    ]
                  }
                },
                "required": [
                  "key",
                  "value"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated metadata",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "description": "True when the metadata was saved.",
                      "type": "boolean"
                    },
                    "metadata": {
                      "description": "The full metadata map after the merge.",
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "success",
                    "metadata"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "description": "Human-readable message stating what went wrong.",
                      "type": "string"
                    },
                    "details": {
                      "description": "Extra context some errors attach, e.g. the offending field or id."
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "The API key or session is missing, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The caller is authenticated but not allowed to perform this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  }
}
