Form (PbotForm)
PbotForm pauses workflow execution to collect structured input from an external party. Unlike PbotApproval, which collects a decision from a designated reviewer, PbotForm collects data from customers, vendors, or partners.
Basic Usage
{
"type": "PbotForm",
"properties": {
"expected_keys": ["shipping_address", "delivery_date", "special_instructions"],
"ttl_seconds": 86400,
"reminder_intervals": [3600, 7200]
}
}
When execution reaches this step, the run pauses and waits for form submission.
Properties Reference
| Property | Type | Required | Description |
|---|---|---|---|
expected_keys |
string[] | Yes | Fields the form expects. Submission must include these keys |
ttl_seconds |
number | No | How long the form stays open before expiring (default: no expiration) |
reminder_intervals |
number[] | No | Seconds after creation to send reminders. [3600, 7200] sends reminders at 1 hour and 2 hours |
Submission Flow
Submitting Form Data
curl -X POST https://your-hyphen.example.com/forms/{runId}/0/submit \
-H "X-Org-Id: acme-corp" \
-H "Content-Type: application/json" \
-d '{
"data": {
"shipping_address": "123 Main St, City, ST 12345",
"delivery_date": "2025-02-15",
"special_instructions": "Leave at door"
}
}'
/forms/:runId/:stepId/submitSubmit form data for a paused PbotForm step.
/forms/pendingList all pending form requests across the organization.
Context After Submission
The submitted data is added directly to the execution context. Each key from the submission becomes accessible via @path:
{
"type": "schedule_delivery",
"properties": {
"address": "@shipping_address",
"date": "@delivery_date",
"notes": "@special_instructions"
}
}
TTL and Expiration
When ttl_seconds is set, the form closes after that duration and stops accepting submissions. Hyphen emits form_expired, advances the paused step without submission data, and continues the run. Downstream steps should handle missing form values on the expiry path.
Use TTL for time-sensitive workflows where stale input would be harmful, such as a vendor onboarding form that is valid for 24 hours.
Reminder Intervals
The reminder_intervals array specifies when reminders should be sent (in seconds after the form is created). This triggers reminder webhook events that your application can use to send follow-up notifications.
{
"reminder_intervals": [3600, 7200, 43200]
}
This sends reminders at 1 hour, 2 hours, and 12 hours after the form is created.
Two kinds of form, one renderer
Hyphen has two kinds of form. One renderer, <hyphen-form>, serves both.
Form pause (PbotForm) |
Intake form | |
|---|---|---|
| What it is | A running case waits for named keys | A schema and a trigger |
| Tied to a run | Yes. Submitting resumes the run, once | No. Submitting starts a workflow or a published process |
| Created by | A workflow step | POST /external-forms or POST /forms/generate |
| Where a person sees it | The task sidebar, Process Studio, or <hyphen-form run-id step-id> |
The hosted page https://<gateway>/forms/<formId>, or <hyphen-form form-id> in your product |
| Who can submit | A signed-in session | Anyone with the link, or a signed-in person when the form requires it |
| Best for | A vendor supplies shipping details mid-workflow | A client disputes a charge and a case starts |
A form pause is a task: it appears on the SDK event stream as task:created with kind: "form", the sidebar lists it beside approvals with Fill it in, and the webhooks carry form_pause_created, form_submitted, and form_expired.
Both kinds share one schema contract, form_schema_v1: pages of fields, each field with a key, a type (text, number, email, date, multiline, content, select, checklist, range, money, and placeholders for file, signature, table, lookup, computed), a label, and optional help, required, default, options, min, max, step, unit. The renderer also accepts the legacy builder's component array, a flat field list, and a JSON-Schema object. The submitted payload is always flat.
A paused step's fields come, in order, from a schema on the element, a schema authored for the step, a schema generated for the step when the organization has the agent_forms feature, or one text field per expected key.
See Forms for the components and the hosted page, and Forms that start work for the walkthrough.
ā Next: Custom Table