---
title: "Test the AI SDR on a reply"
method: POST
path: "/api/agent-tests"
tags: ["agent_tests"]
---

# Test the AI SDR on a reply

`POST /api/agent-tests`

## Request

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

Test the AI SDR on a real reply: the thread, and the lead's message to answer (its newest when omitted). It reads the thread up to that message and nothing after it, classifies it and writes the reply it would send, as a test: every check runs, nothing is sent, booked, written to the thread or learned. Comes back running: read it with get_agent_test until done, then compare reply.text with person.text, what a person answered. 422 no_lead_message, 503 runtime_unavailable.

Contract:
- MCP tool `start_agent_test`, registry package `mcp.unibox/agent_tests`, mount `unibox.agent-memory`.
- Operation `create`, response envelope `create`.
- Flags: none.

## Request body

- StartAgentTestRequest: Request body of `start_agent_test`.
  - `conversation_sid` string, required: The thread to test on (ub_cv_…).
  - `from_message_sid` string: The lead's message to answer (ub_ms_…); the thread's newest message of the lead's when omitted. The thread is read up to it and nothing after it.

## Response `200`

`create` success envelope.

- StartAgentTestResponse
  - `success` true, required
  - `operation` 'create', required
  - `item` object, required
    - `sid` string, required: Test sid (ub_at_…).
    - `team_sid` string, required: Owning team (ts_tm_…, external - gs.service.id).
    - `agent_sid` string, required: The team's agent (ub_ag_…).
    - `conversation_sid` string, required: The thread it ran on (ub_cv_…).
    - `from_message_sid` string, required: The lead's message it answered (ub_ms_…): the thread was read up to it.
    - `state` 'running' | 'done' | 'failed', required: running (its turns are out), done, failed (error_code says why).
    - `created_by` object, required: Who started it.
      - `actor_type` 'user' | 'support' | 'api_key' | 'system' | 'agent', required
      - `actor_sid` string, nullable, required
      - `team_sid` string, required
      - `actor_name` string, nullable: The OAuth client that acted ("Claude", "n8n"); null for a user, an API key or a system job.
      - `oauth_client_sid` string, nullable: The acting OAuth client (id_oc_*); null off the OAuth path.
      - `reason` string, nullable: Why a system actor wrote the row (snapshot_capture_job, ...); null otherwise.
      - `permissions` object, required: Internal audit context: the grant set the actor held at write time. Not a contract.
      - `cluster_id` integer, nullable: Internal audit context: the cluster that served the write.
      - `trace_id` string, nullable: Internal audit context: the trace id of the request that wrote the row.
    - `classify_run_sid` string, nullable, required: The test's classify turn (ub_rn_…); get_agent_run include made reads how the reply was made off the reply run.
    - `reply_run_sid` string, nullable, required: The test's writing turn (ub_rn_…); null while the classify runs and when none writes.
    - `read` object, nullable, required: What the classify made of the message; null while it runs.
      - `scenario_key` string, nullable, required: The scenario the classify read the message as.
      - `confidence` number, nullable, required: Its confidence, 0 to 1.
      - `summary` string, nullable, required: Where the lead stands, two sentences.
      - `reason` string, nullable, required: Why it read it so.
      - `custom_scenario_sid` string, nullable, required: The team's own scenario it matched (ub_sc_…), when one.
      - `questions` string[], required: The questions the lead asked, as the classify listed them.
      - `knowledge_miss` string, nullable, required: A question nothing in Knowledge answers above the floor.
      - `level` object, nullable, required: The level the scenario resolves to on this message.
        - `scenario_key` string, required
        - `setting` string, required: The scenario's level as set: autopilot, copilot, conditional, off.
        - `level` string, required: The level the reply resolved to: autopilot, copilot, off.
        - `condition` string, nullable, required: The condition that decided it, in the team's words.
        - `condition_kind` string, nullable, required
      - `hand_off` object, nullable, required: The hand-off the settings would fire on this message; null when none. Judged, never applied.
        - `trigger` string, required: The hand-off that would fire: legal_or_security, pricing_question, call_request, job_seeker, support_request, unknown_question, file_attached, custom.
        - `custom_trigger` string, nullable, required
        - `note` string, nullable, required
    - `reply` object, nullable, required: What the writing turn left; null until done.
      - `kind` 'plan' | 'dialog_reply' | 'none', required: plan: the planning turn, its first message the reply; dialog_reply: the dialog's reply turn; none: no turn writes on this message.
      - `none_reason` 'level_off' | 'mechanical' | 'wrote_nothing' | 'handed', nullable, required: level_off (the scenario is Off), handed (a hand-off would fire), mechanical (the chain carries no message), wrote_nothing (the turn ended without a text).
      - `note` string, nullable: The hand-off's trigger or the mechanical chain's behavior, when none.
      - `text` string, nullable, required: The reply it would send, as the send door checked it; null when none.
      - `files` object[], required: The Knowledge files it would send with the reply.
        - `name` string, required
      - `checks` object[], required: The checks the text went through (the Words, the tracking reveal, the Rules' checks), as the Analyzer reads them.
        - `check` string, required
        - `passed` boolean, required
      - `dialog` object, nullable, required: Where the dialog would stand after the reply, on a dialog reply.
        - `stage` string, nullable, required
        - `move` string, nullable, required
        - `no_reply` boolean, required
    - `person` object, nullable, required: What a person on the team answered the same message with, when one did before the lead wrote again; null otherwise.
      - `message_sid` string, required: The message of ours (ub_ms_…).
      - `text` string, required: What was answered.
      - `author` string, required: user (a person), agent (a draft a person approved).
      - `at` string, required: ISO 8601 UTC.
      - `minutes_after` integer, required: How long after the lead's message it went.
    - `error_code` string, nullable, required: Why it failed: runtime_unavailable, or the turn's own reason.
    - `cost_usd` number, nullable, required: What its turns cost on the model, in US dollars.
    - `created_at` string, required: ISO 8601 UTC.
    - `updated_at` string, required: ISO 8601 UTC.
  - `already_exists` boolean, required
  - `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)
