Items & Forms
Items are the core data model. An item is a notification, question, or task that an agent sends to a human.
Item Lifecycle
open → answered (user submitted form response)
open → dismissed (user dismissed it)
open → expired (TTL elapsed)
open → withdrawn (agent retracted it)
dismissed → open (restored)
expired → open (restored)
withdrawn → open (restored)
any → archived (moved to archive)
archived → any (unarchived)Item Fields
| Field | Type | Description |
|---|---|---|
id | UUID | Auto-generated |
title | string | Required. Display title |
message | string | Optional body text |
level | enum | info / warning / error / success |
status | enum | open / answered / dismissed / expired / withdrawn |
priority | int | 0 (unset), 1 (low), 2 (medium), 3 (high), 4 (urgent) |
form | object | Optional form schema for user input |
actions | array | Optional action buttons |
response | object | Form response (set when answered) |
channel_id | UUID | Optional channel for grouping |
tags | string[] | Free-form labels |
metadata | object | Agent-defined key/value annotations |
assignee_id | UUID | Who is responsible |
parent_id | UUID | Thread parent |
related_to | UUID[] | Symmetric "see also" links |
deadline_at | datetime | User-facing deadline |
snoozed_until | datetime | Hidden until this time |
pinned_at | datetime | Pinned to top of list |
ttl_ms | int | Auto-expire after N milliseconds |
Forms
Forms let agents ask structured questions. A form is a JSON object attached to an item.
Form Schema
json
{
"id": "deploy-approval",
"title": "Approve deployment?",
"description": "Review the changes and approve or reject.",
"fields": [
{
"id": "approved",
"type": "yesno",
"label": "Approve this deploy?",
"required": true,
"yes_label": "Approve",
"no_label": "Reject"
},
{
"id": "notes",
"type": "textarea",
"label": "Notes",
"placeholder": "Any concerns?"
}
],
"pages": [],
"submit_label": "Submit",
"cancel_label": "Cancel"
}Field Types (22)
| Type | Description | Key props |
|---|---|---|
text | Single-line text | placeholder, min_len, max_len, pattern |
textarea | Multi-line text | placeholder, min_len, max_len |
number | Numeric input | min, max |
select | Dropdown single-select | options[] |
multiselect | Multi-select | options[] |
radio | Radio button group | options[] |
checkbox | Boolean checkbox | |
toggle | Toggle switch | |
yesno | Two-button yes/no | yes_label, no_label |
datetime | Date/time picker | |
rating | Star rating | min, max |
slider | Range slider | min, max, step |
issuepicker | Text with suggestions | suggestions[] |
taginput | Tag chip input | suggestions[], max |
repeat | Repeatable sub-form | fields[], min, max |
markdown | Read-only markdown | content |
fileupload | File upload | accept, max_bytes |
diffapproval | Diff review + approve | diff, approve_label, reject_label |
color | Color picker | default (hex) |
money | Currency input | currency (default "USD"), min, max |
percentage | Percentage slider | min (0), max (100), step (1) |
computed | Computed read-only | expression |
Mobile v1 supports 15 types. Deferred to mobile v2: fileupload, diffapproval, markdown.
Conditional Visibility (show_if)
Any field can have a show_if condition that controls whether it's rendered:
json
{
"id": "details",
"type": "textarea",
"label": "Details",
"show_if": {
"field_id": "severity",
"operator": "eq",
"value": "critical"
}
}The details textarea only appears when the severity field equals "critical".
| Operator | Description |
|---|---|
eq | Equal |
neq | Not equal |
gt | Greater than |
lt | Less than |
contains | String contains |
empty | Value is null or empty |
not_empty | Value is present |
Callback URL
Items can have a callback_url. When the item is answered, dismissed, or acknowledged, the server POSTs the response to this URL. See Integrations for details.
Multi-Page Forms
Forms support multi-page navigation with conditional branching:
json
{
"pages": [
{
"id": "page1",
"title": "Basic Info",
"fields": [{"id": "severity", "type": "select", "label": "Severity", "options": [...]}],
"next": {
"kind": "conditional",
"field_id": "severity",
"branches": [
{"value": "critical", "page_id": "page_critical"},
{"value": "low", "page_id": "page_low"}
],
"default": "page_general"
}
}
]
}Templates
Reusable form schemas can be saved as templates:
bash
# Save
curl -X POST http://localhost:3000/api/templates \
-H "Authorization: Bearer TOKEN" \
-d '{"name": "deploy-approval", "schema": {...}}'
# List
curl http://localhost:3000/api/templates \
-H "Authorization: Bearer TOKEN"
# Delete
curl -X DELETE http://localhost:3000/api/templates/deploy-approval \
-H "Authorization: Bearer TOKEN"