{
    "type": "object",
    "properties": {
        "script_path": {
            "type": "string",
            "description": "Path to the script or flow to execute when triggered"
        },
        "is_flow": {
            "type": "boolean",
            "description": "True if script_path points to a flow, false if it points to a script"
        },
        "labels": {
            "type": "array",
            "items": {
                "type": "string"
            },
            "default": []
        },
        "draft_only": {
            "description": "True when this row is a per-user draft with no deployed\ntrigger at the same path. Set by list endpoints when\n`include_draft_only=true` synthesizes the row from the\ndraft. Frontend renders a \"Draft\" badge.\n",
            "type": "boolean"
        },
        "is_draft": {
            "description": "True when the authed user has a per-user draft at this path\n(over a deployed row or a synthesized draft-only row).\nFrontend appends a `*` to the displayed name.\n",
            "type": "boolean"
        },
        "url": {
            "type": "string",
            "description": "The WebSocket URL to connect to (can be a static URL or computed by a runnable)"
        },
        "filters": {
            "type": "array",
            "description": "Array of key-value filters to match incoming messages (only matching messages trigger the script)",
            "items": {
                "type": "object",
                "properties": {
                    "key": {
                        "type": "string"
                    },
                    "value": {}
                },
                "required": [
                    "key",
                    "value"
                ]
            }
        },
        "filter_logic": {
            "type": "string",
            "enum": [
                "and",
                "or"
            ],
            "default": "and",
            "description": "Logic to apply when evaluating filters. 'and' requires all filters to match, 'or' requires any filter to match."
        },
        "initial_messages": {
            "type": "array",
            "nullable": true,
            "description": "Messages to send immediately after connecting (can be raw strings or computed by runnables)",
            "items": {
                "anyOf": [
                    {
                        "type": "object",
                        "properties": {
                            "raw_message": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "raw_message"
                        ]
                    },
                    {
                        "type": "object",
                        "properties": {
                            "runnable_result": {
                                "type": "object",
                                "properties": {
                                    "path": {
                                        "type": "string"
                                    },
                                    "args": {
                                        "type": "object",
                                        "description": "The arguments to pass to the script or flow",
                                        "additionalProperties": true
                                    },
                                    "is_flow": {
                                        "type": "boolean"
                                    }
                                },
                                "required": [
                                    "path",
                                    "args",
                                    "is_flow"
                                ]
                            }
                        },
                        "required": [
                            "runnable_result"
                        ]
                    }
                ]
            }
        },
        "url_runnable_args": {
            "type": "object",
            "description": "Arguments to pass to the script/flow that computes the WebSocket URL",
            "additionalProperties": true,
            "nullable": true
        },
        "can_return_message": {
            "type": "boolean",
            "description": "If true, the script can return a message to send back through the WebSocket"
        },
        "can_return_error_result": {
            "type": "boolean",
            "description": "If true, error results are sent back through the WebSocket"
        },
        "heartbeat": {
            "type": "object",
            "properties": {
                "interval_secs": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "Interval in seconds between heartbeat messages"
                },
                "message": {
                    "type": "string",
                    "description": "Message to send as heartbeat. Use {{state}} as a placeholder for a value extracted from incoming messages (see state_field)."
                },
                "state_field": {
                    "type": "string",
                    "description": "Optional. Top-level JSON field to extract from incoming messages. The extracted value replaces {{state}} in the heartbeat message."
                }
            },
            "required": [
                "interval_secs",
                "message"
            ],
            "nullable": true,
            "description": "Optional periodic heartbeat message configuration"
        },
        "error_handler_path": {
            "type": "string",
            "description": "Path to a script or flow to run when the triggered job fails"
        },
        "error_handler_args": {
            "type": "object",
            "description": "Arguments to pass to the error handler",
            "additionalProperties": true
        },
        "retry": {
            "type": "object",
            "description": "Retry configuration for failed executions",
            "properties": {
                "constant": {
                    "type": "object",
                    "description": "Retry with constant delay between attempts",
                    "properties": {
                        "attempts": {
                            "type": "integer",
                            "description": "Number of retry attempts"
                        },
                        "seconds": {
                            "type": "integer",
                            "description": "Seconds to wait between retries"
                        }
                    }
                },
                "exponential": {
                    "type": "object",
                    "description": "Retry with exponential backoff (delay doubles each time)",
                    "properties": {
                        "attempts": {
                            "type": "integer",
                            "description": "Number of retry attempts"
                        },
                        "multiplier": {
                            "type": "integer",
                            "description": "Multiplier for exponential backoff"
                        },
                        "seconds": {
                            "type": "integer",
                            "minimum": 1,
                            "description": "Initial delay in seconds"
                        },
                        "random_factor": {
                            "type": "integer",
                            "minimum": 0,
                            "maximum": 100,
                            "description": "Random jitter percentage (0-100) to avoid thundering herd"
                        }
                    }
                },
                "retry_if": {
                    "type": "object",
                    "description": "Conditional retry based on error or result",
                    "properties": {
                        "expr": {
                            "type": "string",
                            "description": "JavaScript expression that returns true to retry. Has access to 'result' and 'error' variables"
                        }
                    },
                    "required": [
                        "expr"
                    ]
                }
            }
        }
    },
    "required": [
        "script_path",
        "is_flow",
        "url",
        "filters",
        "can_return_message",
        "can_return_error_result"
    ]
}
