On Action Required

View as Markdown
Fired when the source asks for something only your customer can provide. A one-time code sent to their phone, a push notification to confirm, a security question, an extra field the engine could not know in advance. The execution is **paused, not broken**, and it is waiting for you. **This is the one event you cannot replace with patience.** The others tell you about a run that is progressing on its own; this one is a run that will expire unless you answer, and the window is the institution's, not ours. The alternative is polling the state every few seconds for every execution in flight. <Steps> <Step title="Read the state"> [Execution State](api:GET/executions/handler/v1/{execution_id}) answers `423` and carries `form_schema` — the exact fields to collect, with `x-meta.timeout` saying how long you have — and `action_required_expires`, the deadline as a date. </Step> <Step title="Collect the values from your customer"> Ask for exactly what the form declares, nothing more. The values travel like any other secret: you may send them encrypted. </Step> <Step title="Send them back"> [Resume an Execution](api:PUT/executions/handler/v1/{execution_id}) hands the answer over and the engine carries on from where it stopped. </Step> </Steps> <CardGroup cols={2}> <Card title="MFA_REQUIRED" icon="fa-solid fa-shield-halved"> A strong-authentication challenge: a code, a push confirmation, a signature. </Card> <Card title="INPUT_REQUIRED" icon="fa-solid fa-keyboard"> Anything else the engine needs and could not know in advance — a security question, a contract to choose. </Card> </CardGroup> **`producer` says who is asking**: `engine` while the login is being resolved, or the feature's own code — `accounts_read`, say — when one feature raised the challenge on its own. <Warning> **Move fast.** A code issued by a bank expires on the institution's timetable, usually a couple of minutes. Past the deadline the execution is aborted with `ACTION_TIMEOUT` and has to be started again. </Warning> <Note> **This event only happens when you asked for it to be possible.** An execution started with `customer_interaction_available: false` never pauses: if the source raises a challenge, the execution ends instead. </Note>