OTP approvals
OTP approvals is the second-supervisor gate for the two highest-leverage pieces of Orbit Verify:- an OTP message template going live, and
- a resend burst on an existing verification (a flurry of resend requests against one verification).
409 Conflict. This is the same four-eyes pattern used for campaign launches, so the queue reads identically across gated surfaces.
Turn the policy on or off
The policy has three fields:
Update the policy from the dashboard (any owner/admin), or read and write it over the API:
Work the queue
Every pending item shows the requester (the teammate’s user id), the kind (otp_template or resend_burst), the rendered template body or the burst metadata it would release, and when it was queued.
Work the queue from the dashboard under Outbound → OTP approvals, or over the API:
- Approve releases the request. A gated template goes live; a gated resend burst re-enters the ordinary Verify dispatch chain and delivers through the normal channel router — approval decides nothing more than the policy gate, it never touches the delivery path itself.
- Reject holds the request back. The body may carry an optional
reasonso the requester sees why; with noreasonthe requester just sees the rejection. - Self-approve is a hard no. If the approver is the same user as the requester, the API returns
409 Conflict. It is the single most-asked-about constraint — the whole point of a four-eyes gate is that the person who submits is not the person who signs.
403.
Read a pending item
A queued resend burst looks like this:otp_template rows, rendered_body carries the exact template copy the approver judges; for resend_burst rows it stays null and the approver decides against the burst_count / window_seconds pair. When the gate is off, the pending endpoint returns an empty list and nothing accrues.
Troubleshooting
- “I approved my own request and it came back with 409.” Working as designed — the approver must not be the requester. Have a second owner or admin decide the item, or reject it yourself to clear the queue.
- “The pending queue is empty even though I just submitted a template.” The gate is off (
require_approval_defaultisfalse), or the burst fell belowresend_burst_thresholdwhen a threshold is set. Also check your role: the queue is supervisor-only and other roles get403. - “Approving a burst doesn’t resend immediately.” Approval only releases the gate. The resend is handed back to the normal Verify dispatch and still respects the verification’s expiry, channel fallback, and rate limits — nothing is sent from a parallel path.