List rule runs
What your rules have actually done, one row per rule per message.
Runs the real call against your workspace, with your own key.
GET /rules/runs
What your rules have actually done, one row per rule per message.
Example
Needs rules:read. Newest first. ruleId narrows to one rule and threadId answers "why did this message end up here".
curl "$OE/rules/runs?threadId=thr_5d31c2a8…&limit=25" -H "$AUTH"{ "object": "list", "data": [ { "object": "rule_run", "id": "rrun_9c1f0a4b7e05d3862c1f0a44", "ruleId": "rul_7f3a1c94e05d3862c1f0a44b", "ruleName": "Receipts to their own label", "threadId": "thr_5d31c2a8…", "messageId": "msg_c5f21cc6…", "sender": "[email protected]", "subject": "Your receipt", "actions": ["label", "archive"], "failures": [], "createdAt": "2026-08-29T11:04:12.000Z" } ], "hasMore": false, "nextCursor": null}actions holds what was APPLIED and failures holds what was refused, as type: reason. They are separate lists rather than one annotated list because "the rule archived it" and "the rule tried to archive it" are different facts, and a log that conflates them cannot answer either question. These are bare action types. The values live on the rule, and wouldApply on a test is the one place they are spelled out.
A suppressed auto-reply appears here, as reply: auto-reply suppressed because the message carries List-Id, and it is the only place it does. Nothing else surfaces a reply that deliberately did not go, and "why did my out-of-office not answer that" is otherwise unanswerable.
ruleName is stored on the row rather than joined at read time, so the log still reads correctly after a rule is renamed or deleted. A row naming a rule that no longer exists is the normal case, not a dangling reference.
The one-auto-reply-per-sender-per-day limit is enforced by a claim row in the same table, which this log does not return: it is why a second out-of-office to the same sender inside a day never fires.