---
title: "Rewrite agent reply as a test"
method: POST
path: "/api/agent-runs/{sid}/rewrite"
tags: ["agent_runs"]
---

# Rewrite agent reply as a test

`POST /api/agent-runs/{sid}/rewrite`

## Request

- Base URL: `https://beta.getsales.io/unibox/v1`
- URL: `https://beta.getsales.io/unibox/v1/api/agent-runs/{sid}/rewrite`
- Auth: HTTP bearer and API key in header `Team-SID`

Write an AI SDR reply again as a test, after a fix: a turn of the kind that made it, over its kept context with the Knowledge and the golden set picked again for the same message, checked like any reply and never sent. result.run is the test run (outcome test): read it with get_agent_run until it is done (its words in record.text) or failed. 409 rewrite_unavailable (written before turns were kept, or 90 days ago), rewrite_of_test; 503 runtime_unavailable.

Contract:
- MCP tool `rewrite_agent_reply`, registry package `mcp.unibox/agent_runs`, mount `unibox.agent-memory`.
- Operation `action`, response envelope `action`.
- Flags: none.

## Path parameters

- `sid` string, required: The run whose reply is written again (ub_rn_…), a row of the Analyzer's log; a test run is 409 rewrite_of_test.

## Response `200`

`action` success envelope.

- RewriteAgentReplyResponse
  - `success` true, required
  - `operation` 'action', required
  - `action` string, required: kebab-case verb; matches the route segment.
  - `item` unknown, required
  - `result` object, required
    - `run` object, required: The test run as it stands after the dispatch: the maker's kind on the same thread, outcome test, test_of_run_sid the run asked about, born running. Read it back with get_agent_run until it is done (its words in record.text) or failed (error_code).
      - `sid` string, required: Agent run sid (ub_rn_…).
      - `team_sid` string, required: Owning team (ts_tm_…, external - gs.service.id).
      - `agent_sid` string, nullable, required: The AI SDR the turn ran as (ub_ag_…), frozen at the dispatch (block 10, 2026-10-30); null on a row from before.
      - `conversation_sid` string, required: The thread this work ran on (ub_cv_…).
      - `kind` 'classify' | 'plan' | 'execute_step' | 'dialog_reply', required: classify = one debounced classification of an inbound burst; plan = a strategize turn that builds or replaces the thread plan; execute_step = one due plan step; dialog_reply = one goal-led live-dialog reply.
      - `state` 'pending' | 'running' | 'done' | 'failed' | 'canceled', required: pending = armed, waiting for execute_at or a queue slot; running = claimed; done / failed / canceled are terminal. A turn that reports a failure after its message or its plan was written is done, not tried again: the work stands. canceled = the work was no longer wanted (the lead wrote again, the plan was canceled or replaced, or a person rewrote the step the run was working for). failed means the retries were exhausted and the escalation policy fired.
      - `execute_at` string, nullable, required: ISO 8601 UTC the run is due at (the debounce or timer clock); null = run now. Sort ascending over pending rows to see what fires next.
      - `trigger_message_sid` string, nullable, required: The newest inbound message that armed a classify or dialog_reply (ub_ms_…). It is the freshness anchor: a newer inbound cancels the run at claim time.
      - `trigger_signal` 'awaiting_reply' | 'opened_not_replied' | 'clicked_not_replied' | 'multi_opened' | 'accepted_not_replied' | 'note_read_not_replied' | 'reacted_not_replied' | 'invited_us' | 'followed_us' | 'lead_messaged_first' | 'unanswered_inbound' | 'draft_pending' | 'escalated_open' | 'task_overdue' | 'went_quiet' | 'reactivated' | 'invite_pending' | 'connection_removed' | 'blocked_us' | 'deleted_message' | 'bounced' | 'bounced_hard' | 'complained' | 'booking_link_sent' | 'objective_reached' | 'viewed_our_profile' | 'visited_our_site' | 'visited_not_replied' | 'visited_key_page' | 'multi_visited' | 'submitted_form' | 'company_visited_our_site' | 'no_people' | 'thin_coverage' | 'nobody_reached' | 'no_engagement' | 'no_reply' | 'exhausted' | 'dormant' | 'dm_missing', nullable, required: The signal that armed a plan run when no reply did (accepted_not_replied, reacted_not_replied or clicked_not_replied): the thread gained the name and the agent owes it a move, strategized under the signal_followup behavior. Null on every other run; a classify landing on the thread re-arms the run and clears it.
      - `scenario_key` string, nullable, required: The platform scenario the classify matched, max 64 chars (the vocabulary is owned by conversations). null on non-classify runs.
      - `confidence` number, nullable, required: Classification confidence, 0..1. Below the platform floor it trips the low_confidence escalation.
      - `extracted` object, nullable, required: Entities the classify pulled out of the reply; null when nothing was extracted.
        - `return_date` string: Out of office: the ISO 8601 date the prospect is back.
        - `resume_date` string: Not now: the ISO 8601 date the prospect said to come back.
        - `proposed_time` string: Meeting or reschedule ask: the time the prospect proposed, in their own words ("next week", "Thursday 15:00 CET"), never converted to a timestamp.
        - `referred_contact` object: Referral or wrong person: the person the prospect pointed at. A LinkedIn link is never stored, only the identity it resolves to.
          - `name` string: Their name, as the reply gave it.
          - `role` string: Their role or title, as the reply gave it.
          - `email` string: Their email address, as the reply gave it.
          - `ln_nickname` string: LinkedIn vanity slug, the name after linkedin.com/in/, lowercased.
          - `ln_id` string: LinkedIn profile URN (ACoAA…), when the reply linked the profile by it.
          - `sn_id` string: Sales Navigator URN (ACwAA…), from a Sales Navigator link.
          - `recruiter_id` string: Recruiter URN (AEMAA…), from a Recruiter link.
          - `ln_member_id` string: The member id a URN decodes to, digits only: one person across the three URNs.
        - `objection_topic` string: Objection: what the prospect objected to, in a few words of their own.
        - `objection_kind` 'price' | 'timing' | 'has_solution' | 'other': Objection family (AgentRunObjectionKindEnum), when one clearly fits. Logged for analysis; it is not a scenario of its own.
      - `reason` string, nullable, required: The model's own explanation of the decision, max 512 chars. This is what the thread timeline pill renders, and what to quote when a user disputes a classification.
      - `custom_scenario_sid` string, nullable, required: The custom scenario that matched (ub_sc_…), which takes precedence over the built-in behavior; null when none did.
      - `behavior` 'answer_interested' | 'meeting_request_book' | 'answer_info_request' | 'referral_capture' | 'not_now_defer' | 'ooo_delay_ping' | 'auto_reply_skip' | 'wrong_person_referral' | 'reschedule_meeting' | 'cancel_meeting' | 'return_to_orchestration' | 'close_not_interested' | 'handle_objection' | 'stoplist_do_not_contact' | 'vendor_pitch_skip' | 'acknowledge_low_signal' | 'followup_no_reply' | 'signal_followup' | 'followup_after_person', nullable, required: The built-in competence module driving a plan or execute run; null on classify runs and on custom-scenario-driven work.
      - `behavior_version` integer, nullable, required: Version of that module at run time: the audit stamp that makes a past decision reproducible.
      - `playbook_source` 'platform' | 'edited' | 'custom', nullable, required: Whose playbook the run planned under (2026-10-12): platform (the seed as it ships), edited (the team's version of it) or custom (a scenario of the team's own with steps of its own). Stamped on a classify run that planned a mechanical playbook by rule and on a plan run whose pack resolved one; null on every other run.
      - `playbook_version` integer, nullable, required: That playbook's version: the seed's, or 1 on a custom scenario's own steps. With behavior_version, the audit says which version of whose playbook planned.
      - `plan_sid` string, nullable, required: The plan created (kind plan) or executed (kind execute_step), ub_pl_…; null otherwise.
      - `step_id` integer, nullable, required: Which step of plan_sid this run executed, or the use_playbook step a Playbook turn rides; null on a run outside a plan.
      - `dialog_turn` 'reply' | 'stall' | 'followup', nullable, required: What a Playbook dialog turn is for (2026-10-19, ConversationDialogTurnEnum): reply, the reply to the lead's message; stall, the offer the stall rule forces after days of silence; followup, a follow-up after the offer with a new angle (or the one nudge after a yes). Null on every other run.
      - `guidance` string, nullable, required: The user's "try again, but..." steering on a regenerate, max 1024 chars. It rides the turn's context pack.
      - `regenerates_message_sid` string, nullable, required: The draft the user discarded (ub_ms_…); its body joins the context pack as the previous draft.
      - `llm_log_ref` string, nullable, required: The runner's transcript of the turn (the SDK's stream, on the runner's host), max 255 chars. It holds no context pack: what a reader needs of the turn is record.
      - `error_code` string, nullable, required: Terminal failure code once the retries are exhausted, max 64 chars; null otherwise. Group failures by it before reading any transcript.
      - `cost_usd` number, nullable, required: What the turn cost on the model in US dollars, as the runner reported it (2026-10-19): the agent's meter. A thread's spend is the sum over its runs, read in credits (25 a dollar) against the agent's credits_cap_per_conversation. Null on a run that never reported and on rows from before.
      - `example_sids` string[], nullable, required: The golden set rows the turn's pack carried (2026-10-20, ub_eg_…, at most five, golden first): what the reply was written from. Null on a turn that carried none.
      - `words_caught` object[], nullable, required: The Words the send door refused this run's messages for (2026-10-20), each with how often; the turn wrote the sentence again. Null when none.
        - `never` string, required
        - `times` integer, required
      - `knowledge_miss` string, nullable, required: A classify run only: the lead's question the Knowledge pick found nothing for above the floor, up to 500 chars. Null otherwise.
      - `outcome` 'written' | 'edited' | 'unsure' | 'waiting' | 'handed' | 'test', nullable, required: What became of the reply the run stands for (2026-10-21, the Analyzer's log): written, edited (a person changed its words before it went), unsure (it went as written and the lead's question found nothing in Knowledge), waiting (a draft waits for an OK), handed (a hand-off took the thread to a person instead), test (a rewrite, never sent). Null: no row of the log.
      - `approved_by_user_sid` string, nullable, required: The person who approved the reply the run stands for, as its message carries it (2026-10-27, block AC8), stamped with the outcome. Null on a reply that went out on its own (the Analyzer's Sent itself) and on a run with no reply.
      - `test_of_run_sid` string, nullable, required: A test run's original (ub_rn_…): the run whose reply rewrite_agent_reply wrote again. Null on every live run.
      - `test_sid` string, nullable, required: The test from a real reply this run is a turn of (ub_at_…, start_agent_test on /mcp/unibox/agent-memory, 2026-10-28): its classify of the lead's message or the reply written after it. Null on every live run and on a rewrite's test run.
      - `record` object, nullable, required: What the turn read, decided, wrote and was checked by (2026-10-21), every part optional: read (a classify's ranking, signals, questions, model numbers, hand-off), gather (the pack's inputs, used or only read), decision, write (model, tokens, prompt parts, first draft), checks, tries, spans and mix (what the reply's words came from), made_by (the plan run that wrote a planned send), text (a test run's reply), edit_says, files (the Knowledge files that went out with the reply, block AC3). Null on older runs.
        - `read` object
        - `gather` object
        - `decision` object
        - `write` object
        - `checks` object[]
        - `tries` integer
        - `spans` object[]
        - `mix` object
        - `made_by` string, nullable
        - `text` string, nullable
        - `edit_says` object, nullable
        - `files` object[]: The Knowledge files that went out with the reply (block AC3, 2026-10-26): the answer each came with.
          - `answer_sid` string, required
          - `question` string, required
          - `name` string, required
      - `hint_sids` string[], nullable, required: The Analyzer's hints the run opened or counted on its completion (2026-10-26, ub_hn_…, at most ten; search_agent_hints on /mcp/unibox/agent-memory): a classify's missing answers, a writing turn's missing dialogue. Null on a run that left none.
      - `created_at` string, required: ISO 8601 UTC.
      - `updated_at` string, required: ISO 8601 UTC.
  - `meta` object, required
    - `trace_id` string, required: UUID v7; same 128-bit value as the X-Trace-Id header.
    - `span_id` string, required: 16 hex chars, root span of this request.
    - `timestamp` string, required: ISO 8601 UTC (Y-m-dTH:i:sZ), response time.
    - `duration_ms` integer, required: Server-side wall clock.
    - `team_sid` string, nullable: The team this call ran in (the token team, or the team_sid override). Null when unauthenticated; absent from pre-2026-08-20 backends.
    - `actor_type` string, nullable: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends.

## Other responses

- `4XX`: MCP error envelope. `error.code` is one of validation_failed, nothing_to_update, not_found, relation_not_found, invalid_transition, limit_exceeded, payment_required, duplicate_rejected, conflict, delete_blocked, unauthorized, forbidden, rate_limited, not_implemented.
- `5XX`: MCP error envelope with `error.code` internal_error or service_unavailable.

---

[API](https://skmtc.dev/getsales/apis/getsales-public-contract-gs-service-unibox.md) - [All operations](https://skmtc.dev/getsales/apis/getsales-public-contract-gs-service-unibox/llms.txt) - [OpenAPI document](https://skmtc.dev/getsales/apis/getsales-public-contract-gs-service-unibox/revisions/8f1bc317897f?raw)
