sayintel
Endpoint

Rescore drafts

POST/api/public/v1/campaigns/{campaign_id}/rescoreswrite

Score-only QA on drafts exactly as stored: runs the LLM judge once per speaker on the stored M1/M2/M3 and the deterministic hard-fail gate on the same bytes, then writes qa_score, qa_reasons, qa_flags, role_fit and needs_human. NEVER rewrites a body - use it after update_message (hand-edited rows are unscored and nothing else re-scores them) or to refresh a stale verdict. A clean score releases a founder_edited row; a hard fail anywhere in the trio holds all three; rows flagged awaiting review (e.g. copilot_rewritten_awaiting_review) stay held at any score until a person clears them with approve_message. If the judge would have rewritten a slot, its stored text did not clear 8 and the score is capped at 7. Targets speaker_ids and/or message_ids (message_ids writes only those slots); with neither it takes the campaign's evaluated-but-unscored drafts. Skips speakers with a sent slot, fewer than 3 drafts, or drafts the QA finalizer has not evaluated yet. At most 25 speakers per call; the rest come back in deferred_speaker_ids. Costs model calls, no credits: pass dry_run=true for cost_preview.

Request

curl -X POST "https://sayintel.com/api/public/v1/campaigns/<campaign_id>/rescores" \
  -H "Authorization: Bearer $SAYINTEL_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{}'

Try it out

Try it outPOST/api/public/v1/campaigns/{campaign_id}/rescoreswrite

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.

Paste an API key to run.

Path parameters

NameInTypeRequiredDescription
campaign_idpathstringyes—

Body

NameInTypeRequiredDescription
speaker_idsbodyarrayno—
message_idsbodyarraynoScore these speakers' trios, but write the verdict only onto these rows.
dry_runbodybooleannoWhen true nothing is written, started, or spent. The tool returns only cost_preview so an agent can estimate credits first.

Response

{
  "ok": true,
  "tool": "rescore_drafts",
  "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.
  • Accepts dry_run: true and always returns cost_preview before spending anything.
  • Same capability over MCP as the tool rescore_drafts. MCP setup.