Get a conversation and its results
const url = 'https://example.com/MIDWATER_BASE_URL/v1/conversations/example';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url https://example.com/MIDWATER_BASE_URL/v1/conversations/example \ --header 'Authorization: Bearer <token>'Returns the conversation, its scoring status, its outcome and the result of every check.
id is Midwater’s ID or your external_id. Results appear once status is done.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Midwater’s conversation ID or your external_id.
Responses
Section titled “Responses”The conversation.
object
Scoring status. failed means scoring didn’t finish after Midwater’s automatic retries (five attempts in all); it can be re-run from the app.
How the conversation ended for the caller. resolved: Resolved. unresolved: Unresolved.
escalated: Handed to a person. not_real_inquiry: Not a customer call (sales, spam, wrong number),
kept out of resolution rates. null while scoring, or when no outcome check applied.
Planned renames: escalated becomes handed_to_person and not_real_inquiry becomes not_customer_call;
accept both until the change is announced in the changelog.
The conversation in the Midwater app.
object
object
object
agent is your AI agent, user the caller or chat user, human_agent a person who took over.
Offset from the start of the conversation.
Speech-recognition confidence for this turn (voice).
Something your agent did: a tool call, a transfer, a handoff. Extra properties are kept. The built-in booking checks turn on the first time a tool_call whose name contains book or schedul arrives. A transfer or handoff event marks the conversation as handed to a person.
object
Where a transfer went.
object
object
Stable key of the check; use it with the feedback endpoint.
shadow checks are scored but never alert.
Likelihood that the problem occurred, 0 to 1.
pass: no problem found. fail: Midwater found this problem. uncertain: unclear; a person should look.
not_applicable: didn’t apply to this conversation. met / not_met: for gating questions
(for example, whether this was a real customer inquiry).
The chosen option for multiple-choice checks.
rule: decided from the events you sent. model: Midwater’s model read the whole conversation. llm_judge: a second review for unclear conversations (planned rename: second_review; accept both). human: someone on your team.
One or two sentences on why.
The transcript turns the result points to.
Midwater’s opaque version of how the result was scored, e.g. 2026-10-06.3.
Examples
A scored conversation
{ "id": "cmv0187nm005po3016rag4dcg", "external_id": "call_8f2a91", "channel": "voice", "status": "done", "outcome": "resolved", "dashboard_url": "https://app.example/conversations/cmv0187nm005po3016rag4dcg", "started_at": "2026-10-05T14:02:11.000Z", "ended_at": "2026-10-05T14:06:40.000Z", "ended_by": "caller", "agent": { "id": "front-desk", "name": "Front desk", "version": "1.0.0" }, "group": null, "transcript": [ { "speaker": "agent", "text": "Thanks for calling, this call may be recorded. How can I help?" }, { "speaker": "user", "text": "I need to move my appointment to Thursday.", "asr_confidence": 0.93 } ], "events": [ { "type": "tool_call", "name": "reschedule_appointment", "status": "success", "at_ms": 61000 } ], "metadata": { "language": "en" }, "results": [ { "check_key": "appointment_not_completed", "check_name": "Appointment request not completed", "check_version": 1, "check_status": "active", "score": 0, "verdict": "pass", "choice": null, "decided_by": "rule", "reason": "A booking tool call succeeded.", "evidence_turns": [], "scorer_version": "2026-10-01.1", "latency_ms": 0 } ]}Headers
Section titled “Headers”Example
req_8Jx2kQ4mT9The request’s ID, also in error bodies as error.request_id. Quote it when contacting support.
Missing, malformed, unknown or revoked API key.
object
object
Stable machine-readable type. Each has a set status: invalid_json 400, authentication_error 401,
permission_denied 403, not_found 404, method_not_allowed 405, idempotency_conflict 409, payload_too_large 413,
validation_error 422, rate_limited 429, server_error 500, service_unavailable 503.
Types not yet returned are planned. Treat a type you don’t know by its status class.
Human-readable; may change.
Validation errors by dotted path, e.g. transcript.0.speaker. _root for the body as a whole.
object
The request’s ID, the same as the Midwater-Request-Id header.
Example
{ "error": { "type": "authentication_error", "message": "Missing or invalid API key. Use Authorization: Bearer mw_test_… or mw_live_…" }}The key is valid but not allowed to do this.
object
object
Stable machine-readable type. Each has a set status: invalid_json 400, authentication_error 401,
permission_denied 403, not_found 404, method_not_allowed 405, idempotency_conflict 409, payload_too_large 413,
validation_error 422, rate_limited 429, server_error 500, service_unavailable 503.
Types not yet returned are planned. Treat a type you don’t know by its status class.
Human-readable; may change.
Validation errors by dotted path, e.g. transcript.0.speaker. _root for the body as a whole.
object
The request’s ID, the same as the Midwater-Request-Id header.
Example
{ "error": { "type": "permission_denied", "message": "This key can't do that", "request_id": "req_8Jx2kQ4mT9" }}Not found in the key’s environment.
object
object
Stable machine-readable type. Each has a set status: invalid_json 400, authentication_error 401,
permission_denied 403, not_found 404, method_not_allowed 405, idempotency_conflict 409, payload_too_large 413,
validation_error 422, rate_limited 429, server_error 500, service_unavailable 503.
Types not yet returned are planned. Treat a type you don’t know by its status class.
Human-readable; may change.
Validation errors by dotted path, e.g. transcript.0.speaker. _root for the body as a whole.
object
The request’s ID, the same as the Midwater-Request-Id header.
Example
{ "error": { "type": "not_found", "message": "Conversation not found" }}The path exists but doesn’t support this method. Allow lists the methods it does support.
object
object
Stable machine-readable type. Each has a set status: invalid_json 400, authentication_error 401,
permission_denied 403, not_found 404, method_not_allowed 405, idempotency_conflict 409, payload_too_large 413,
validation_error 422, rate_limited 429, server_error 500, service_unavailable 503.
Types not yet returned are planned. Treat a type you don’t know by its status class.
Human-readable; may change.
Validation errors by dotted path, e.g. transcript.0.speaker. _root for the body as a whole.
object
The request’s ID, the same as the Midwater-Request-Id header.
Example
{ "error": { "type": "method_not_allowed", "message": "GET isn't supported here; use POST", "request_id": "req_8Jx2kQ4mT9" }}Headers
Section titled “Headers”Example
POSTThe methods the path supports, e.g. POST.
Too many requests. Wait Retry-After seconds. The limits are published when they’re set.
object
object
Stable machine-readable type. Each has a set status: invalid_json 400, authentication_error 401,
permission_denied 403, not_found 404, method_not_allowed 405, idempotency_conflict 409, payload_too_large 413,
validation_error 422, rate_limited 429, server_error 500, service_unavailable 503.
Types not yet returned are planned. Treat a type you don’t know by its status class.
Human-readable; may change.
Validation errors by dotted path, e.g. transcript.0.speaker. _root for the body as a whole.
object
The request’s ID, the same as the Midwater-Request-Id header.
Example
{ "error": { "type": "rate_limited", "message": "Too many requests", "request_id": "req_8Jx2kQ4mT9" }}Headers
Section titled “Headers”Seconds to wait before retrying.
Requests allowed in the current window. The numbers are published when the limits are set.
Requests left in the current window.
Seconds until the window resets.
Something went wrong on Midwater’s side. Safe to retry with the same Idempotency-Key.
object
object
Stable machine-readable type. Each has a set status: invalid_json 400, authentication_error 401,
permission_denied 403, not_found 404, method_not_allowed 405, idempotency_conflict 409, payload_too_large 413,
validation_error 422, rate_limited 429, server_error 500, service_unavailable 503.
Types not yet returned are planned. Treat a type you don’t know by its status class.
Human-readable; may change.
Validation errors by dotted path, e.g. transcript.0.speaker. _root for the body as a whole.
object
The request’s ID, the same as the Midwater-Request-Id header.
Example
{ "error": { "type": "server_error", "message": "Something went wrong on our side" }}Midwater is briefly unavailable. Retry with backoff, honouring Retry-After when present.
object
object
Stable machine-readable type. Each has a set status: invalid_json 400, authentication_error 401,
permission_denied 403, not_found 404, method_not_allowed 405, idempotency_conflict 409, payload_too_large 413,
validation_error 422, rate_limited 429, server_error 500, service_unavailable 503.
Types not yet returned are planned. Treat a type you don’t know by its status class.
Human-readable; may change.
Validation errors by dotted path, e.g. transcript.0.speaker. _root for the body as a whole.
object
The request’s ID, the same as the Midwater-Request-Id header.
Example
{ "error": { "type": "service_unavailable", "message": "Midwater is briefly unavailable", "request_id": "req_8Jx2kQ4mT9" }}Headers
Section titled “Headers”Seconds to wait before retrying.