Edit a draft, capture the diff, and send (human authority)
POST /v1/admin/orgs/{org_id}/projects/{project_id}/reviews/{id}/edit-send
Durable-send deployments commit authorization and the frozen send obligation before returning 202. Temporary failures retry automatically; after one hour unaccepted work requires reconfirmation. A queued response does not mean Sent. The following synchronous response is retained for older deployments only. The human supplies an edited subject/body. The platform captures the proposed-vs-sent diff into a system_diff turn (deterministic Go diff, $0 LLM), approves under the revision+version CAS, then performs the authenticated send of the EDITED content via the COMPOSER’s inbox and records terminal success. Irreversible once returned; a stale draft or CAS race 409s.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters ”Request Body required
Section titled “Request Body required ”A human-authority review action body (console plane, D17). revision + version are the CAS naming the draft the human acted on (a mismatch is a 409 STALE). subject/body and recipient edits are supplied only on edit-send; feedback is the optional rule-birth signal (D7, empty allowed).
object
Edited subject (edit-send only).
Edited body text (edit-send only).
Replace To on edit-send. Omission preserves the proposed recipients. At most 50 recipients across all roles.
Replace Cc on edit-send. Omission preserves; an empty array removes all Cc recipients.
Replace Bcc on edit-send. Omission preserves; an empty array removes all Bcc recipients.
Optional decision comment / rule-birth signal.
Responses
Section titled “ Responses ”Edited, diffed, and sent.
The approve / edit-send success result. The platform performed the authenticated send via the COMPOSER’s inbox; the send is irreversible once returned.
object
Whether the accepted message has a resolvable saved Sent copy. Archive failure never resends mail.
Per-recipient counts by transport state. Absent states have count zero.
object
Example
sentApproved and queued. Provider acceptance is pending.
Durable send authorization accepted. Local queue custody is not provider acceptance. Follow status_url; never create a replacement while an attempt is unresolved.
object
Headers
Section titled “Headers ”Submission status resource.
Invalid request.
The canonical error envelope. error is a stable machine code.
object
Stable error code (e.g. unauthorized, forbidden, not_found, invalid, quota_exceeded, rate_limited).
Example
forbiddenHuman-readable detail (never leaks internals).
Example
missing required scopeMachine-readable quota reason. inbox_limit_exceeded means billing account inbox capacity across all organizations and projects sharing that account; enrollment_token_mailbox_budget_exhausted means the enrollment key lifetime creation allowance. Read message for recovery; inbox counts are separate from sending quotas.
Consumed plus reserved units.
Requested additional units.
Next UTC usage-period boundary; pending reservations survive this boundary.
Missing or invalid credential.
The canonical error envelope. error is a stable machine code.
object
Stable error code (e.g. unauthorized, forbidden, not_found, invalid, quota_exceeded, rate_limited).
Example
forbiddenHuman-readable detail (never leaks internals).
Example
missing required scopeMachine-readable quota reason. inbox_limit_exceeded means billing account inbox capacity across all organizations and projects sharing that account; enrollment_token_mailbox_budget_exhausted means the enrollment key lifetime creation allowance. Read message for recovery; inbox counts are separate from sending quotas.
Consumed plus reserved units.
Requested additional units.
Next UTC usage-period boundary; pending reservations survive this boundary.
Authenticated but lacking the required scope, or out of quota.
The canonical error envelope. error is a stable machine code.
object
Stable error code (e.g. unauthorized, forbidden, not_found, invalid, quota_exceeded, rate_limited).
Example
forbiddenHuman-readable detail (never leaks internals).
Example
missing required scopeMachine-readable quota reason. inbox_limit_exceeded means billing account inbox capacity across all organizations and projects sharing that account; enrollment_token_mailbox_budget_exhausted means the enrollment key lifetime creation allowance. Read message for recovery; inbox counts are separate from sending quotas.
Consumed plus reserved units.
Requested additional units.
Next UTC usage-period boundary; pending reservations survive this boundary.
Resource not found.
The canonical error envelope. error is a stable machine code.
object
Stable error code (e.g. unauthorized, forbidden, not_found, invalid, quota_exceeded, rate_limited).
Example
forbiddenHuman-readable detail (never leaks internals).
Example
missing required scopeMachine-readable quota reason. inbox_limit_exceeded means billing account inbox capacity across all organizations and projects sharing that account; enrollment_token_mailbox_budget_exhausted means the enrollment key lifetime creation allowance. Read message for recovery; inbox counts are separate from sending quotas.
Consumed plus reserved units.
Requested additional units.
Next UTC usage-period boundary; pending reservations survive this boundary.
A Review Loop conflict, as problem+json. Branch on code, NOT on the 409 status; the four codes demand opposite behavior. stale: the revision/version you named is no longer current (a human moved the draft) and NOTHING was mutated; errors[] carries the current state, revision and version, so re-apply your change on top and resubmit with the new parent_revision (retry, bounded to ~3). born_stale: the redraft was built against an older rule high-water; re-read the rules and resubmit, or restamp_review if nothing genuinely changed (at most one retry per high-water). wrong_state: this VERB is illegal from the current state but the draft is still live; NEVER retry the same verb; errors[] repeats an allowed_action entry per verb that IS legal right now. terminal: the review is already sent/auto_sent/cancelled; nothing will ever succeed, stop retrying, and a front_run_next review event carries the outcome. send_needs_reconciliation: a prior attempt is unconfirmed and parked for recover-by-Message-ID; do NOT resend, poll the review.
RFC-9457 problem+json error body. code is a closed machine enum clients switch on; type is a dereferenceable URI under https://extrovert.dev/problems/. Served as application/problem+json.
object
Structured support failure reason without changing the existing code.
Suggested recovery action within existing access.
object
object
object
object
object
Retained text after a concurrent case change.
The CLOSED machine code. The Review Loop members split what used to be a single opaque conflict, because an agent must take a DIFFERENT action on each: stale (the revision/version you named is no longer current; nothing was mutated; re-read, re-apply, resubmit; retryable, bounded) and born_stale (built against an older rule high-water; re-read the rules or restamp_review; at most one retry per high-water) are the ONLY retryable 409s. wrong_state means this VERB is illegal from the current state while the draft is still live; never retry the same verb, read the state and the repeated allowed_action hints in errors[] and pick a legal one. terminal means the review is already sent/auto_sent/cancelled and nothing will EVER succeed; stop, and drain your review events for the outcome. send_needs_reconciliation means a prior send is unconfirmed and parked. Do not resend. Poll instead. unavailable (503) is the retryable fail-closed answer when a dependency could not be read; it carries Retry-After and is distinct from not_configured, which is permanent for this deployment.