---
title: "Structured flow answers"
method: GET
path: "/v1/conversations/{id}/answers"
tags: ["Flows"]
---

# Structured flow answers

`GET /v1/conversations/{id}/answers`

## Request

- Base URL: `https://api.cadencercs.com`
- URL: `https://api.cadencercs.com/v1/conversations/{id}/answers`
- Auth: HTTP bearer

**The reason to run a flow.** `/messages` returns raw text with no step id and no chip payload, so results were otherwise only recoverable by re-parsing a transcript and guessing which reply answered which question.

Safe to poll; also announced as a `completed` event on `GET /v1/events`.

## Path parameters

- `id` string, required

## Response `200`

Answers so far.

- FlowAnswers: Structured results of a server-driven flow — the reason to run one. `outcome` and `final` exist so one request answers "is anything more coming". Without them `done:false, completion:0` meant three different things — still waiting, closed early, and opted out — and telling them apart cost a second call per poll.
  - `conversationId` string
  - `state` string: The conversation's own state, e.g. `OPEN`, `CLOSED`, `CLOSED_OPTOUT`.
  - `outcome` 'awaiting_reply' | 'completed' | 'closed_early' | 'opted_out'
  - `final` boolean: True when nothing further will arrive on this conversation.
  - `flowId` string, required
  - `flowName` string
  - `done` boolean, required: True once the closing has been sent.
  - `completion` number, required: Fraction of the flow's base steps answered, 0–1. Follow-ups are bonus and do not inflate it.
  - `currentStepId` string, nullable: Null when the flow is done.
  - `answers` object[], required
    - `stepId` string, required
    - `question` string, nullable: The step's text, so results read without holding the flow definition alongside.
    - `text` string, required: What they actually sent.
    - `optionIndex` number: **1-based position among the REPLY chips** — the same number the SMS fallback tells the recipient to reply with, so it means the same thing on both legs. Action chips are not counted and never carry one: there is no number you could reply with to open a URL. Absent on an action tap, which arrives with `optionLabel` and `chipAction` instead. `optionLabel` is provided so you never have to index at all.
    - `optionLabel` string: The matched chip's label.
    - `freeText` boolean: True when they typed something rather than choosing an offered option.

## Other responses

- `401`: Missing, unknown or revoked API key.
- `403`: Key suspended, or scoped to a different brand than the one addressed.
- `404`: No conversation with that id on this key or account.
- `409`: This conversation has no flow attached.
- `500`: Unexpected server error. The body is always JSON.

---

[API](https://skmtc.dev/cadencercs/apis/cadence-api.md) · [All operations](https://skmtc.dev/cadencercs/apis/cadence-api/llms.txt) · [OpenAPI document](https://skmtc.dev/cadencercs/apis/cadence-api/revisions/9438443c2081?raw)
