Skip to content

Ask and answer

Any Action can stop to ask a Party a Question and resume when it is answered, from the Portal, email, chat, MCP, the SDK or the CLI.

Any Action can stop mid-run to ask a Question, and it resumes when the answer arrives. The one asking is any Worker; the one asked is any Party, the Customer included.

Ask

patentpad.com drafts provisional patents. Its drafting Agent finds two inventions in one disclosure and asks the Customer which one to claim:

TypeScript
import { $ } from 'startup-builder'

const question = await $.Action.ask({
  action: 'action_42',
  to: 'customer_9',
  text: 'Your disclosure describes two inventions. Which should the draft claim?',
  choices: ['The hinge', 'The latch', 'Both, as two drafts'],
  answerBy: '2026-10-25T17:00:00Z',
})

Action.ask holds the Action pending with reason awaitingInput and posts the Question in the Thread of the record it concerns, here the Order. choices renders as a picker; schema renders typed fields; with neither, the answer is free text. Every Question is kept on its Action with its answer.

Answer from anywhere

The asked Party answers wherever they already are. Each path calls Action.answer, and the Action resumes on the first valid answer.

Where the Party isWhat they see
The Startup's PortalA form: choices as a picker, schema as fields
EmailThe Question in one Message; the reply is the answer
A connected chat workspaceA card with the choices as buttons (Chat delivery)
An MCP clientAn elicitation request from the server
The SDK or the CLIThe pending Action, answered with one call
TypeScript
await $.Action.answer({ action: 'action_42', question: 'question_1', payload: { choice: 'The hinge' } })
Terminal
npx startup-builder do Action.answer --json '{"action":"action_42","question":"question_1","payload":{"choice":"The hinge"}}'

A free-text reply in the Thread is kept as a Message. An Agent maps it onto the Question's choices or schema and records the answer, citing the Message.

Who may answer

Only the asked Party answers, or a Worker acting for them under a Mandate. An Agent that answers for a Human records both: by is the Agent and for is the Human. Any other answer is refused and changes nothing.

awaitingInput is the one pending reason that asks the caller to act. npx startup-builder pending lists every Action waiting on the signed-in identity, Questions first.

Clocks

While the Customer holds a Question, the Order's delivery window and its service level pause. While a Worker holds one, both keep running, so a slow internal answer counts against the Startup.

At answerBy, an unanswered Question ends the wait by the rule its Verb declares: proceed on a stated default, or cancel the Action. Either way, the outcome is recorded on the Question.

Events

Asking emits Action.asked, and answering emits Action.answered. A Watch on either reaches any system that tracks open Questions, such as a support queue counting time spent waiting on Customers.