Approve message
Record a PERSON's decision that drafts are fine as written: clears needs_human and needs_redo, removes review-hold flags (e.g. copilot_rewritten_awaiting_review, *_awaiting_review, agent_authored_*, founder_rejected_*) and stamps founder_approved_text_<date>. Only call it when the user has read the text and said to approve it. Target message_ids or speaker_ids (all their unsent slots). Refuses, per row, anything never evaluated or carrying a hard fail. It never invents a score: qa_score is left as is, so a row approved with no score or below 8 is approved but still not ready_to_send, and the response says so (run rescore_drafts first). Does not send or push by itself, but on a campaign with HeyReach auto-push armed clearing the hold is part of sending, so there it requires the 'send' token scope and is refused otherwise.
Request
curl -X POST "https://sayintel.com/api/public/v1/campaigns/<campaign_id>/approvals" \
-H "Authorization: Bearer $SAYINTEL_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{}'Try it out
Sent as a bearer token to this site only, and kept in this tab's session storage. It is never written to disk or sent anywhere else.
Path parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| campaign_id | path | string | yes | — |
Body
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| message_ids | body | array | no | — |
| speaker_ids | body | array | no | Approve every unsent slot of these speakers. |
Response
{
"ok": true,
"tool": "approve_message",
"kind": "write",
"data": { ... },
"error": null
}Notes
- Scope required: write. How scopes work.
- Accepts Idempotency-Key. A retry with the same key replays the first result instead of repeating the work.
- Same capability over MCP as the tool approve_message. MCP setup.