Advance the flow
flow_proceedGenerate and send the next step's payload in an ONDC flow, checking preconditions and recording results. Supports required inputs, dry runs, and payload overrides to avoid abandoned runs.
Instructions
The loop driver. Takes the next step this mock owns, checks its preconditions, generates its payload from the flow's own mock config, and POSTs it to the participant — then records both the payload and whatever the step saved for later steps. If the step needs values it comes back INPUT_REQUIRED with the declarations; call again with inputs. If the next move is the participant's it comes back WAITING; call flow_await. Pass dry_run: true to generate and inspect a payload without sending it, or trigger_extra to fire a named side-channel step. When a step is blocked because the flow's own config generates a non-compliant payload, payload_overrides patches the offending fields so the run can continue instead of being abandoned. Sending the flow's first action is what mints its transaction_id, which the answer then reports.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| inputs | No | Values for a step reported as INPUT_REQUIRED, as a **flat** object: it becomes `sessionData.user_inputs` verbatim and the step's generator reads the declared field names off the top of it. Do not nest them under the declaration's name — `inputs_required.fields` lists the keys to send, and `inputs_required.example` shows the shape. For a manual step pass {id: '<step_key>'} — naming it is what triggers it. | |
| dry_run | No | Generate and record the payload but do not send it, so it can be inspected first. Nothing reaches the participant. Combines with `payload_overrides` to check a patch before it goes out. | |
| flow_id | No | The flow started with flow_start. Works before the transaction id exists, so prefer it. | |
| session_id | Yes | Session returned by session_create. | |
| trigger_extra | No | Fire a named side-channel step from the flow's extra sequence instead of advancing the main sequence. Only steps this mock owns can be fired. | |
| transaction_id | No | A specific transaction. Only known once the flow's first action has crossed the wire. | |
| payload_overrides | No | Patch the generated payload before it is validated and sent: a map of JSONPath to replacement value, e.g. {"$.context.bpp_uri": "https://np.example.com/seller"}. This is the escape hatch for a **flow config that is itself wrong** — a step whose generator emits a non-compliant field cannot otherwise be got past, and abandoning the run costs the participant its compliance report. Not a validation bypass: the gate still runs on the patched payload, so an override that does not fix the finding still blocks. Paths must be concrete (no wildcards, filters or `..`), `$.context.transaction_id` is refused, and they apply to this call only — a chained step never inherits them. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| ack | No | How the participant answered a SENT step. | |
| action | No | Its protocol action or form type. | |
| events | No | What has happened in this session since your last call — the participant's callbacks, steps sent automatically, refusals, form submissions. Attached to every session-scoped result and delivered exactly once, so read it here instead of polling. Absent when nothing happened. `more` above zero means call record_get_events for the rest. | |
| reason | No | Machine-readable cause of a block. | |
| details | No | Everything known about the block — requirement codes, errors. | |
| message | Yes | ||
| outcome | Yes | ||
| ack_body | No | The participant's synchronous response, verbatim. | |
| form_url | No | Where the form lives, for whichever side has to open it. | |
| step_key | No | The step this outcome is about. | |
| form_role | No | 'fill' — the participant hosts the form and this mock must submit it. 'host' — this mock serves the form and the participant must submit it. | |
| overrides | No | Paths patched by `payload_overrides` before this payload was validated and sent. Present only when a step was patched, which makes it not a clean step: the participant was tested against a payload this flow's own config did not produce, and the compliance report says so. | |
| payload_id | No | Handle for the payload produced. Read it with record_get_payload. | |
| validation | No | How the generated payload judged against the spec. Present whenever a payload was produced, including one that was blocked or drafted rather than sent. `status: "unavailable"` means it went unchecked — the payload was still sent, because refusing to act on our own outage would strand the run. | |
| http_status | No | ||
| input_problems | No | Why the supplied `inputs` were refused. Present only when values were sent and did not match — nothing was generated or sent, so fixing them and calling again costs the run nothing. | |
| transaction_id | No | This flow run's transaction id. Absent until the flow's first action crosses the wire — it belongs to whoever sends that action, so when the participant moves first it is theirs to choose and unknowable until their call lands. Address the run by flow_id until then. | |
| expected_action | No | The action now expected from the participant. | |
| inputs_required | No | What the step declares it needs. Send `fields` as a flat object under flow_proceed's `inputs`. | |
| override_problems | No | Why `payload_overrides` were refused. Nothing was patched, generated or sent — every path is judged before any is written, so correcting them and calling again costs the run nothing. |