Skip to content

Get a conversation and its results

GET
/v1/conversations/{id}
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.

id
required
string

Midwater’s conversation ID or your external_id.

The conversation.

Media typeapplication/json
object
id
required
string
external_id
required
string
channel
required
string
Allowed values: voice chat
status
required

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.

string
Allowed values: queued evaluating done failed
outcome
required

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.

string | null
Allowed values: resolved unresolved escalated not_real_inquiry handed_to_person not_customer_call
dashboard_url
required

The conversation in the Midwater app.

string format: uri
started_at
string | null format: date-time
ended_at
string | null format: date-time
ended_by
string | null
agent
required
object
id
required
string
name
required
string
version
required
string | null
group
required
object
id
required
string
name
required
string
transcript
required
Array<object>
object
speaker
required

agent is your AI agent, user the caller or chat user, human_agent a person who took over.

string
Allowed values: agent user human_agent
text
required
string
>= 1 characters
start_ms

Offset from the start of the conversation.

integer
end_ms
integer
asr_confidence

Speech-recognition confidence for this turn (voice).

number
<= 1
events
required
Array<object>

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
type
required
string
>= 1 characters
name
string
status
string
target

Where a transfer went.

string
at_ms
integer
key
additional properties
any
metadata
required
object
key
additional properties
any
results
required
Array<object>
object
check_key
required

Stable key of the check; use it with the feedback endpoint.

string
check_name
string
check_version
required
integer
check_status
required

shadow checks are scored but never alert.

string
Allowed values: draft shadow active
score

Likelihood that the problem occurred, 0 to 1.

number | null
<= 1
verdict
required

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).

string
Allowed values: pass fail uncertain not_applicable met not_met
choice

The chosen option for multiple-choice checks.

string | null
decided_by

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.

string | null
Allowed values: rule model llm_judge second_review human
reason

One or two sentences on why.

string | null
evidence_turns

The transcript turns the result points to.

Array
scorer_version
required

Midwater’s opaque version of how the result was scored, e.g. 2026-10-06.3.

string
latency_ms
integer | null

Examples

Exampledefault

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
}
]
}
Midwater-Request-Id
string
Example
req_8Jx2kQ4mT9

The request’s ID, also in error bodies as error.request_id. Quote it when contacting support.

Missing, malformed, unknown or revoked API key.

Media typeapplication/json
object
error
required
object
type
required

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.

string
Allowed values: invalid_json authentication_error permission_denied not_found method_not_allowed idempotency_conflict payload_too_large validation_error rate_limited server_error service_unavailable
message
required

Human-readable; may change.

string
fields

Validation errors by dotted path, e.g. transcript.0.speaker. _root for the body as a whole.

object
key
additional properties
Array<string>
request_id

The request’s ID, the same as the Midwater-Request-Id header.

string

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.

Media typeapplication/json
object
error
required
object
type
required

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.

string
Allowed values: invalid_json authentication_error permission_denied not_found method_not_allowed idempotency_conflict payload_too_large validation_error rate_limited server_error service_unavailable
message
required

Human-readable; may change.

string
fields

Validation errors by dotted path, e.g. transcript.0.speaker. _root for the body as a whole.

object
key
additional properties
Array<string>
request_id

The request’s ID, the same as the Midwater-Request-Id header.

string

Example

{
"error": {
"type": "permission_denied",
"message": "This key can't do that",
"request_id": "req_8Jx2kQ4mT9"
}
}

Not found in the key’s environment.

Media typeapplication/json
object
error
required
object
type
required

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.

string
Allowed values: invalid_json authentication_error permission_denied not_found method_not_allowed idempotency_conflict payload_too_large validation_error rate_limited server_error service_unavailable
message
required

Human-readable; may change.

string
fields

Validation errors by dotted path, e.g. transcript.0.speaker. _root for the body as a whole.

object
key
additional properties
Array<string>
request_id

The request’s ID, the same as the Midwater-Request-Id header.

string

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.

Media typeapplication/json
object
error
required
object
type
required

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.

string
Allowed values: invalid_json authentication_error permission_denied not_found method_not_allowed idempotency_conflict payload_too_large validation_error rate_limited server_error service_unavailable
message
required

Human-readable; may change.

string
fields

Validation errors by dotted path, e.g. transcript.0.speaker. _root for the body as a whole.

object
key
additional properties
Array<string>
request_id

The request’s ID, the same as the Midwater-Request-Id header.

string

Example

{
"error": {
"type": "method_not_allowed",
"message": "GET isn't supported here; use POST",
"request_id": "req_8Jx2kQ4mT9"
}
}
Allow
string
Example
POST

The methods the path supports, e.g. POST.

Too many requests. Wait Retry-After seconds. The limits are published when they’re set.

Media typeapplication/json
object
error
required
object
type
required

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.

string
Allowed values: invalid_json authentication_error permission_denied not_found method_not_allowed idempotency_conflict payload_too_large validation_error rate_limited server_error service_unavailable
message
required

Human-readable; may change.

string
fields

Validation errors by dotted path, e.g. transcript.0.speaker. _root for the body as a whole.

object
key
additional properties
Array<string>
request_id

The request’s ID, the same as the Midwater-Request-Id header.

string

Example

{
"error": {
"type": "rate_limited",
"message": "Too many requests",
"request_id": "req_8Jx2kQ4mT9"
}
}
Retry-After
integer

Seconds to wait before retrying.

RateLimit-Limit
integer

Requests allowed in the current window. The numbers are published when the limits are set.

RateLimit-Remaining
integer

Requests left in the current window.

RateLimit-Reset
integer

Seconds until the window resets.

Something went wrong on Midwater’s side. Safe to retry with the same Idempotency-Key.

Media typeapplication/json
object
error
required
object
type
required

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.

string
Allowed values: invalid_json authentication_error permission_denied not_found method_not_allowed idempotency_conflict payload_too_large validation_error rate_limited server_error service_unavailable
message
required

Human-readable; may change.

string
fields

Validation errors by dotted path, e.g. transcript.0.speaker. _root for the body as a whole.

object
key
additional properties
Array<string>
request_id

The request’s ID, the same as the Midwater-Request-Id header.

string

Example

{
"error": {
"type": "server_error",
"message": "Something went wrong on our side"
}
}

Midwater is briefly unavailable. Retry with backoff, honouring Retry-After when present.

Media typeapplication/json
object
error
required
object
type
required

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.

string
Allowed values: invalid_json authentication_error permission_denied not_found method_not_allowed idempotency_conflict payload_too_large validation_error rate_limited server_error service_unavailable
message
required

Human-readable; may change.

string
fields

Validation errors by dotted path, e.g. transcript.0.speaker. _root for the body as a whole.

object
key
additional properties
Array<string>
request_id

The request’s ID, the same as the Midwater-Request-Id header.

string

Example

{
"error": {
"type": "service_unavailable",
"message": "Midwater is briefly unavailable",
"request_id": "req_8Jx2kQ4mT9"
}
}
Retry-After
integer

Seconds to wait before retrying.