---
title: "Record a fenced human Decision"
method: POST
path: "/api/assistant/work-items/{id}/interactions"
tags: ["Mailzero Assistant"]
---

# Record a fenced human Decision

`POST /api/assistant/work-items/{id}/interactions`

## Request

- Base URL: `https://domani.run`
- URL: `https://domani.run/api/assistant/work-items/{id}/interactions`
- Auth: HTTP bearer

Choose an option, give an instruction, take over, snooze, ignore, correct, report the trust verdict (phishing or legitimate), or approve or reject a waiting plan (an approved plan executes at once, with its receipts in the answer). The call is fenced by work_item_version and replayed idempotently by idempotency_key. Choosing or instructing prepares an exact draft that still goes through the normal reply flow; this endpoint never sends mail. Requires the assistant:write scope.

## Path parameters

- `id` string, required

## Request body

- object
  - `scope` 'item' | 'sender' | 'sender_domain' | 'situation': With type ignore: also mute the sender, its domain, or this recurring situation so it never comes back.
  - `verdict` 'phishing' | 'legitimate': With type report: the person's verdict on the trust signals. Phishing closes the matter, mutes the sender and closes its other live matters; legitimate clears the suspect verdict and its reasons.
  - `plan_id` string: With type approve or reject: the waiting action plan (proposed or escalated).
  - `reason` string: With type reject: why, kept on the plan.
  - `type` 'choose' | 'instruct' | 'take_over' | 'snooze' | 'ignore' | 'correct' | 'delegate' | 'approve' | 'reject' | 'report' | 'tag', required
  - `add` string[]: With type tag: tags to put on the matter (a proposed one confirmed, or one by hand; lower case, letters, digits and hyphens). A tag added once is learned: the next matter of the same project gets it without a question.
  - `remove` string[]: With type tag: tags to take off the matter (a proposal named here is declined). The learned page forgets a tag for good.
  - `agent_slug` string, nullable: With type delegate: the slug of your agent to hand the item to, or null to take it back.
  - `member_id` string, nullable: With type delegate: the user id of a member of your workspace to hand the item to instead of an agent; they find it under handed_to_you in their Today and work it through the tasks endpoints under their own access.
  - `work_item_version` integer, required
  - `decision_id` string
  - `decision_version` integer
  - `option_id` string
  - `instruction` string
  - `until` string, date-time
  - `remind_at` string, date-time
  - `field` string
  - `correction` string
  - `idempotency_key` string, required

## Response `200`

Interaction recorded or idempotently replayed

- object
  - `ok` boolean
  - `work_item` AssistantWorkItem: One grounded item of the Today queue. Every field is a proposal derived from mail; the source message stays the only truth.
    - `id` string
    - `version` integer
    - `status` 'open' | 'needs_judgment' | 'snoozed' | 'waiting' | 'handled' | 'ignored'
    - `title` string
    - `summary` string
    - `ask` string, nullable: The single thing the owner must do or decide, or null.
    - `category` 'invoice' | 'payment_notice' | 'payment_failure' | 'refund_request' | 'signature_request' | 'meeting_request' | 'calendar_change' | 'support_ticket' | 'partner_inquiry' | 'recurring_alert' | 'account_notice' | 'newsletter' | 'legal_notice' | 'internal_handover' | 'shipping_notice' | 'phishing' | 'other', nullable: The kind of matter the analysis found (an invoice, a meeting request, a newsletter...), or null when no analysis said. Rules match it as the label category:<kind>.
    - `tags` string[]: The person's tags on the matter (CT-01b): confirmed once or set by hand, each one a label on the thread at the provider. Rules match them as the label tag:<name>.
    - `proposed_tags` string[]: The tags the engine proposes for the matter (one per project it named), not yet confirmed. Confirm one with the tag interaction; it then applies to the next matter of the same project without a question.
    - `suspect` boolean: The trust signals found the sender suspect: the matter sits in the Suspect section, is never Now, carries no decision, and no effect runs on it until the person reports it legitimate.
    - `suspect_reasons` string[]: Why it looks suspect, one sentence per signal (a failed authentication, a diverging Reply-To, a lookalike domain, a borrowed name, a first contact about money, an instruction to the assistant, a secret asked by return mail).
    - `sender` object, nullable
      - `address` string
      - `name` string, nullable
      - `kind` 'human' | 'automated' | 'self' | 'harness'
    - `recurrence` object: How often this same situation came back: one item, N messages.
      - `count` integer
      - `first_seen_at` string, nullable
      - `last_seen_at` string, nullable
    - `mailbox` object
      - `id` string
      - `address` string
      - `name` string, nullable
      - `operator` 'human' | 'agent'
      - `agent` object, nullable
        - `name` string
        - `emoji` string, nullable
    - `opened_at` string, nullable
    - `delegated_to` string, nullable: The slug of the agent the owner handed this item to, or null.
    - `delegation_rule` object, nullable: The standing delegation that handed this item over, and why it matched; suspended once the owner took the item back.
      - `id` string
      - `why` string, nullable
      - `suspended` boolean
    - `unread` boolean: True until the owner opens the item after its latest change.
    - `messages` object[]: The source messages behind this item, newest first.
      - `id` string
      - `subject` string, nullable
      - `from` string
      - `received_at` string
      - `conversation_id` string, nullable
    - `history` object[]: What already happened in this matter, oldest first: one line per earlier message.
      - `message_id` string
      - `occurred_at` string
      - `sender` string
      - `title` string
    - `source` object
      - `type` string
      - `conversation_id` string, nullable
      - `event_id` string
      - `revision` integer
    - `attention` object
      - `level` 'now' | 'needs_you' | 'fyi' | 'quiet'
      - `reason` string
      - `confidence` string
      - `deadline` string, nullable
    - `analysis` object
      - `coverage` string
      - `warnings` string[]
    - `evidence_refs` string[]
    - `entity_refs` string[]
    - `snoozed_until` string, nullable
    - `decision` object, nullable
      - `id` string
      - `version` integer
      - `status` string
      - `question` string
      - `options` object[]
        - `id` string
        - `label` string
        - `recommended` boolean
        - `outcome` string
    - `plan` object, nullable
      - `id` string
      - `status` string
      - `expires_at` string
  - `plan_id` string, nullable

## Other responses

- `401`: Missing or invalid API key
- `409`: Stale revision or clarification required
- `429`: Rate limit exceeded - wait and retry

---

[API](https://skmtc.dev/domani/apis/domani-run-api.md) · [All operations](https://skmtc.dev/domani/apis/domani-run-api/llms.txt) · [OpenAPI document](https://skmtc.dev/domani/apis/domani-run-api/revisions/7679f8159533?raw)
