MOLTED EMAIL
CLI Reference

molted overrides

Human-in-the-loop overrides

CommandDescription
molted overrides countsGet override queue counts
molted overrides queueList items in an override queue. Valid queue names: needs_approval, blocked_by_policy, high_risk, spam.
molted overrides held-messagesList held messages
molted overrides releasePrint the human decision link for a held message. Releasing is human-only (D3), this does not call the API.
molted overrides reject-heldPrint the human decision link for a held message. Rejecting a held message is human-only (D3), this does not call the API.
molted overrides approvePrint the human decision link for a pending send. Approving is human-only (D3), this does not call the API.
molted overrides reject-sendReject a held thread: rejects its pending send approvals and trashes the thread. Human-gated with no own-send exception: once the workspace enforces the human gate it returns 403 human_decision_required with a decisionUrl, even for a send you created.
molted overrides editPrint the human decision link for a pending override. Editing is human-only (D3), this does not call the API.
molted overrides escalateEscalate a thread: sets its status to escalated and keeps any review queue it is in
molted overrides not-spamMark a thread not-spam: releases it from the spam queue, or from needs_approval when the classifier itself routed it there for a safety verdict. Records spam feedback for the sender. Ungated ONLY for a thread currently in the spam queue that the classifier never held (a plain inbox thread manually reported as spam); gated like a human decision -- prints a decisionUrl and exits non-zero, same as approve/edit/release -- for a needs_approval/high_risk/blocked_by_policy thread, or any safety verdict at all (including one that reads "spam", since it reflects only the latest classified message on the thread). Also refused when a human has taken the thread over, 409 quarantine_verdict on a phishing/malware/abuse/impersonation verdict (release it from Quarantine instead), and 400 for a thread in neither of the two states above.
molted overrides correct-labelCorrect an inbound message's platformLabel (#2277): opt_out, auto_reply, delivery_notice, or none (not any of these). Feedback only: changes no routing, suppression or stored label. Not human-gated.
molted overrides report-spamMove a thread to the spam queue and record spam feedback for the sender.
molted overrides delete-spamResolve and trash a thread in the spam queue, confirming the spam verdict. A classifier-flagged spam thread (needs_approval) is gated like reject: 403 human_decision_required once the gate enforces.
molted overrides spam-statsGet spam feedback stats: total reports, spam vs not-spam counts, unique domains.
molted overrides sender-reputationGet sender reputation stats (spam/not-spam counts, auth pass/fail, score) for a domain.
molted overrides alertsGet alert status

Agent context

Overrides provide a human-in-the-loop approval layer for agent actions. When safety rules or confidence thresholds require human review, messages are held in override queues until a human decides.

Deciding is human-only (D3, epic #1353): approve, edit, release and reject-held do NOT call the API. They print the portal decision link (<portalUrl>/app/decide/<kind>/<id>) and exit non-zero. Share that link with a person on your team -- the CLI cannot make these decisions, even with an operator-scoped key. This is an intentional exception to "all customer features go through the mailbox API": decisions and loosening controls are human-only, reached through the portal/API, and agents only ever get a link.

reject-send still calls the API (POST /v1/agent/override/<threadId>/reject), but that route is gated like approve: it has no own-send (D4) exception, so once the workspace enforces the human gate (the default for new workspaces) it returns 403 human_decision_required with the same kind of link, even for a send you created.

Once a tenant's human gate is in "warn" mode, any call still let through prints a one-line deprecation notice to stderr (Molted-Deprecation: human-gate) -- it will 403 once that tenant enforces.

Check the override queue

molted overrides counts
# → {
#     "needs_approval_outbound": 5,   # held thread with an outbound message (e.g. a send awaiting OK)
#     "needs_approval_inbound":  2,   # held thread with only inbound mail
#     "blocked_by_policy":       0,   # policy engine blocked a send or an inbound message
#     "high_risk":               1,   # thread anomaly or adversarial routing
#     "spam":                    3    # reported as spam (report-spam)
#   }
# Counts cover unresolved threads in mailboxes the key can manage.
# Spam the classifier flagged sits in needs_approval, not in spam.

# Drill into a queue. Valid queue names (distinct from count fields):
#   needs_approval, blocked_by_policy, high_risk, spam
# The two needs_approval_* counts above BOTH surface under the single
# "needs_approval" queue -- use --direction inbound|outbound to filter.
molted overrides queue needs_approval --limit 10
molted overrides queue blocked_by_policy
molted overrides queue high_risk
molted overrides queue spam

molted overrides held-messages --thread-id <id>
# → messages held for a specific thread

Ask a human to decide (these print a decisionUrl, they don't decide)

molted overrides approve <threadId>
# → prints the link for a human to approve the pending send

molted overrides release <messageId>
# → prints the link for a human to release the held message

molted overrides reject-held <messageId>
# → prints the link for a human to reject the held message
#   (alias: molted overrides reject <messageId>)

molted overrides edit <threadId>
# → prints the link for a human to edit and redirect

Reject a held thread's pending sends (this one still calls the API)

molted overrides reject-send <threadId> --reason "Wrong template"
# → { "threadId": "...", "status": "resolved", "auditEventId": "...",
#     "rejectedApprovalIds": [...] }
#   Rejects every pending send approval on the thread and moves the
#   thread to the trash. Only while the human gate is off or in warn:
#   once it enforces, 403 human_decision_required with a decisionUrl,
#   your own send included. 400 if the thread is in no review queue.

Escalate to a human

molted overrides escalate <threadId> --reason "Complex legal question" \
  --assign-to "legal-team"

Spam triage (#1644 -- these call the API directly, no decisionUrl, EXCEPT where noted):

molted overrides not-spam <threadId> --reason "Legitimate sender"
# → clears a thread from the spam queue, OR from needs_approval when the
#   classifier itself put it there with a safety verdict (any other
#   thread is refused 400). Ungated ONLY for a thread currently in the spam queue that the
#   classifier never held (a plain inbox thread a human or agent manually
#   reported as spam). Everything else -- needs_approval, high_risk,
#   blocked_by_policy, or ANY safety verdict at all, including one that
#   reads "spam" -- is gated like a human decision: 403
#   human_decision_required with a decisionUrl, same as approve/edit/
#   release above. (A thread's safety_verdict reflects only the latest
#   classified message on it, so it can't be trusted to tell a corrected
#   false positive apart from a still-dangerous thread -- an earlier
#   phishing message followed by a later spam-only one flips the whole
#   thread's verdict to "spam".) A phishing/malware/abuse/impersonation
#   verdict is refused 409 quarantine_verdict (no decisionUrl): only a
#   release from Quarantine lets it through. Also refused (403) on a
#   thread a human has taken over, regardless of verdict. Records spam feedback on
#   success so the sender's reputation improves; after 3+ HUMAN not-spam
#   marks for the same address it's auto-added to the sender allow-list
#   (never as a whole domain).

molted overrides report-spam <threadId>
# → moves a thread into the spam queue and records spam feedback. Refused
#   (400) when the thread is already needs_approval/high_risk/
#   blocked_by_policy -- use approve/reject/escalate for those instead.
#   Refused (409) on a thread in the trash, (403) on a taken-over thread.

molted overrides delete-spam <threadId>
# → resolves + trashes a thread in the spam queue (confirms spam) and
#   records spam feedback. Refused (403) on a taken-over thread.
#   Also takes a classifier-flagged spam thread (needs_approval with a
#   "spam" verdict), but that is gated like reject: 403
#   human_decision_required with a decisionUrl once the gate enforces,
#   and 409 while the thread has a pending send approval. Any other
#   thread is refused 400.

molted overrides spam-stats
# → { total, spamReports, notSpamReports, uniqueDomains }

molted overrides sender-reputation --domain example.com
# → per-sender rows: spamCount, notSpamCount, authPassCount, ...

Correct a platform label (#2277, not human-gated)

molted overrides correct-label <messageId> none
# → says the message's platformLabel was wrong: none (not any label, e.g.
#   "not an opt-out"), opt_out, auto_reply or delivery_notice. Feedback
#   only: helps Molted learn to sort mail, and changes no routing, no
#   suppression and not the platformLabel anyone reads. Act yourself: for
#   a real opt-out add a suppression (molted suppressions add). A "none"
#   never removes a suppression; removing one is a person's decision.

Monitor alerts

molted overrides alerts
# → { checkedAt, overallLevel, conditions: [{ name, value, level,
#     description }] }: queue staleness and age, send failures, policy
#     blocks, bounce rate, complaints and SLA breaches, each rated
#     ok, warning or critical

Typical supervisor agent loop

  • molted overrides counts # check queue depth
  • molted overrides queue needs_approval # review items
  • For each item needing a decision: share its decisionUrl with a human (reject-send is gated too: once the gate enforces it gets 403 like approve)
  • A plain inbox thread manually reported as spam: molted overrides not-spam works directly. A classifier false positive still sitting in needs_approval/high_risk/blocked_by_policy: not-spam comes back 403 with a decisionUrl to share -- share it. A phishing/malware/abuse/ impersonation verdict comes back 409 quarantine_verdict instead: a person releases it from Quarantine
  • Repeat on interval

Related: molted send, molted threads, molted agents, molted safety

Commands

molted overrides counts

Get override queue counts

molted overrides counts

molted overrides queue

List items in an override queue. Valid queue names: needs_approval, blocked_by_policy, high_risk, spam.

molted overrides queue [options] <queue>
ArgumentDescriptionRequired
<queue>yes
OptionDescriptionDefault
--limit <n>Max items to return (server caps at 50)25
--offset <n>Offset for pagination0
--direction <inbound|outbound>outbound: threads with an outbound message; inbound: threads without one (the split behind the needs_approval_* counts)

molted overrides held-messages

List held messages

molted overrides held-messages [options]
OptionDescriptionDefault
--thread-id <id>Filter by thread ID

molted overrides release

Print the human decision link for a held message. Releasing is human-only (D3), this does not call the API.

molted overrides release <messageId>
ArgumentDescriptionRequired
<messageId>yes

molted overrides reject-held

Print the human decision link for a held message. Rejecting a held message is human-only (D3), this does not call the API.

Alias: reject

molted overrides reject-held <messageId>
ArgumentDescriptionRequired
<messageId>yes

molted overrides approve

Print the human decision link for a pending send. Approving is human-only (D3), this does not call the API.

molted overrides approve <threadId>
ArgumentDescriptionRequired
<threadId>yes

molted overrides reject-send

Reject a held thread: rejects its pending send approvals and trashes the thread. Human-gated with no own-send exception: once the workspace enforces the human gate it returns 403 human_decision_required with a decisionUrl, even for a send you created.

molted overrides reject-send [options] <threadId>
ArgumentDescriptionRequired
<threadId>yes
OptionDescriptionDefault
--reason <reason>Reason for rejection (required) (required)

molted overrides edit

Print the human decision link for a pending override. Editing is human-only (D3), this does not call the API.

molted overrides edit <threadId>
ArgumentDescriptionRequired
<threadId>yes

molted overrides escalate

Escalate a thread: sets its status to escalated and keeps any review queue it is in

molted overrides escalate [options] <threadId>
ArgumentDescriptionRequired
<threadId>yes
OptionDescriptionDefault
--reason <reason>Reason for escalation (required) (required)
--assign-to <user>Free-form assignee, stored as the thread's assigned agent and escalatedTo

molted overrides not-spam

Mark a thread not-spam: releases it from the spam queue, or from needs_approval when the classifier itself routed it there for a safety verdict. Records spam feedback for the sender. Ungated ONLY for a thread currently in the spam queue that the classifier never held (a plain inbox thread manually reported as spam); gated like a human decision -- prints a decisionUrl and exits non-zero, same as approve/edit/release -- for a needs_approval/high_risk/blocked_by_policy thread, or any safety verdict at all (including one that reads "spam", since it reflects only the latest classified message on the thread). Also refused when a human has taken the thread over, 409 quarantine_verdict on a phishing/malware/abuse/impersonation verdict (release it from Quarantine instead), and 400 for a thread in neither of the two states above.

molted overrides not-spam [options] <threadId>
ArgumentDescriptionRequired
<threadId>yes
OptionDescriptionDefault
--reason <reason>Reason for marking not spam

molted overrides correct-label

Correct an inbound message's platformLabel (#2277): opt_out, auto_reply, delivery_notice, or none (not any of these). Feedback only: changes no routing, suppression or stored label. Not human-gated.

molted overrides correct-label <messageId> <label>
ArgumentDescriptionRequired
<messageId>yes
<label>yes

molted overrides report-spam

Move a thread to the spam queue and record spam feedback for the sender.

molted overrides report-spam <threadId>
ArgumentDescriptionRequired
<threadId>yes

molted overrides delete-spam

Resolve and trash a thread in the spam queue, confirming the spam verdict. A classifier-flagged spam thread (needs_approval) is gated like reject: 403 human_decision_required once the gate enforces.

molted overrides delete-spam <threadId>
ArgumentDescriptionRequired
<threadId>yes

molted overrides spam-stats

Get spam feedback stats: total reports, spam vs not-spam counts, unique domains.

molted overrides spam-stats

molted overrides sender-reputation

Get sender reputation stats (spam/not-spam counts, auth pass/fail, score) for a domain.

molted overrides sender-reputation [options]
OptionDescriptionDefault
--domain <domain>Domain to look up (required) (required)

molted overrides alerts

Get alert status

molted overrides alerts

See CLI overview for global options, credentials and output format.