/verify endpoint lets you evaluate a state expression against a process without dispatching an action. The daemon reads the current state, resolves the expression against the objects map, and returns whether it evaluated to true. If the expression is not yet satisfied, the daemon polls the process at its normal probe interval until the expression passes or timeout_ms elapses. Use this endpoint as a pre-flight check before high-stakes actions, as a post-action confirmation step in custom agent loops, or anywhere you need to wait for the application to reach a particular state.
Endpoint
Request Fields
OS process ID of the target application. Provide either
pid or app_id.Stable app identifier from
GET /apps. Provide either app_id or pid.A JavaScript-style predicate evaluated against the
objects map of the current SubstrateState. The expression has access to all dot-notation keys as if they were top-level JavaScript variables, and to the context object for URL-based checks. See the Supported Expressions section below for syntax and examples.How long in milliseconds to poll before returning a result, even if the expression has not yet become
true. Accepted range: 100–30000 ms. If the expression is already true on the first evaluation, the daemon returns immediately without waiting for the full timeout.Response Fields
true if the expression evaluated to a truthy value before timeout_ms elapsed. false if the timeout was reached without the expression becoming true.The expression string that was evaluated, echoed back for confirmation.
The final resolved value of the expression — often a boolean, but can be a number or string when you use comparison operators. Useful for diagnosing why an expression failed to pass.
Human-readable summary of the evaluation result, e.g.
"Expression evaluated to true after 1 poll cycle" or "Timed out after 5000ms — inbox.unread_count was 3, expected 0".Total time in milliseconds from request receipt to response, including all polling cycles.
Number of probe cycles the daemon ran during this verification. A value of
1 means the expression passed on the first read; higher values indicate the daemon had to wait for state to settle.Array of
{ path, before, after } objects listing every field that changed value during the verification window. Empty when poll_cycles is 1 (the expression was already true).The value of the primary operand in the expression at the time of final evaluation. For example, for
"inbox.unread_count < 10" this would be the actual value of inbox.unread_count. Provided when the daemon can infer a single key from the expression.ISO 8601 timestamp of the final evaluation.
Supported Expressions
Expressions are evaluated against theobjects map as if each key were a top-level variable. The context object is also in scope for URL and view checks.
Expressions use JavaScript evaluation semantics. Loose equality (
==) is supported but strict equality (===) is recommended to avoid type coercion surprises with numeric string values.Use Cases
Wait for an action to take effect — AfterPOST /action returns, call POST /verify with the expected post-condition to confirm the application state has settled before moving to the next step in your agent loop.
Pre-flight check before a destructive action — Verify "inbox.emails[0].id == 'msg_expected'" before calling send_reply to ensure the correct thread is selected.
Poll until a background job completes — Set timeout_ms to 30000 and use an expression like "export.status == 'complete'" to block your agent until the application finishes a long-running operation.
Examples
Example Response
Notes
- A
passed: falseresponse uses HTTP200 OK— the endpoint itself succeeded. Only use HTTP status codes to detect transport or authentication errors. - When
timeout_msis large (e.g., 30000), the request will block for up to that long. Ensure your HTTP client’s read timeout is set higher thantimeout_msto avoid client-side disconnects. - The daemon triggers a fresh probe cycle on every poll iteration. Each cycle adds 50–200 ms depending on runtime and application size.
