Skip to main content

Autonomy Levels

Every API key that sends replies operates under an autonomy grant issued by the organization. The grant determines whether POST /v1/replies/:id/send sends immediately or places the draft in the human review queue. No grant means level 0.

A grant is scoped to one API key (the actor), has a level (0–3), and an active window (active_from / optional active_until). Expired or future grants don't count — the key falls back to level 0.

Check your current level at any time with GET /v1/me → autonomy_level.

What each level does​

Verified against the live gateway (2026-09-14):

LevelDirect send?What happens on /sendreason string in the 202What 409s
0 — full review (no active grant)NoDraft queued for human review: 202 queued_for_reviewno_active_autonomy_grantSend on an already-sent reply → 409 already_sent
1 — selectiveNoIdentical queue behavior to level 0: 202 queued_for_reviewreview_required_at_autonomy_level_1Same as level 0
2 — guidedYesSent immediately: 200 "sent" (subject to send rate limits and contact cooldown)n/a (no 202)Second send on the same reply → 409 already_sent
3 — full autonomyYesSame as level 2n/a (no 202)Same as level 2
L0 → L1 changes reporting, not behavior

Moving from level 0 to level 1 changes only the reported reason in the 202/webhook payload and the autonomy level recorded in the Decision Trail (level 1 trail entries also reference the grant). The queue behavior is identical — drafts still require human approval. Direct sending starts at level 2.

One pending draft per reply (replace semantics)​

Below level 2 there is exactly one pending draft per reply:

  • The first send creates the draft: 202 with "replaced": false and a suggestion_id.
  • Every subsequent send replaces that draft: 202 with "replaced": true and the same suggestion_id. The latest body wins.
  • A replaced draft re-enters the review queue even if the previous draft was rejected — replacement is allowed as long as a human still reviews the result.
{
"status": "queued_for_review",
"reply_id": "uuid",
"suggestion_id": "uuid",
"replaced": true,
"reason": "review_required_at_autonomy_level_1"
}

Decision Trail​

Every send attempt — queued or sent — is logged in the Decision Trail with the true granted level at the moment of the call, the acting API key, and (at level ≥ 1) the grant it ran under. Skips and rate-limited attempts are logged too. Silence is never invisible.