Skip to content

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

FieldTypeDescription
idUUIDAuto-generated
titlestringRequired. Display title
messagestringOptional body text
levelenuminfo / warning / error / success
statusenumopen / answered / dismissed / expired / withdrawn
priorityint0 (unset), 1 (low), 2 (medium), 3 (high), 4 (urgent)
formobjectOptional form schema for user input
actionsarrayOptional action buttons
responseobjectForm response (set when answered)
channel_idUUIDOptional channel for grouping
tagsstring[]Free-form labels
metadataobjectAgent-defined key/value annotations
assignee_idUUIDWho is responsible
parent_idUUIDThread parent
related_toUUID[]Symmetric "see also" links
deadline_atdatetimeUser-facing deadline
snoozed_untildatetimeHidden until this time
pinned_atdatetimePinned to top of list
ttl_msintAuto-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)

TypeDescriptionKey props
textSingle-line textplaceholder, min_len, max_len, pattern
textareaMulti-line textplaceholder, min_len, max_len
numberNumeric inputmin, max
selectDropdown single-selectoptions[]
multiselectMulti-selectoptions[]
radioRadio button groupoptions[]
checkboxBoolean checkbox
toggleToggle switch
yesnoTwo-button yes/noyes_label, no_label
datetimeDate/time picker
ratingStar ratingmin, max
sliderRange slidermin, max, step
issuepickerText with suggestionssuggestions[]
taginputTag chip inputsuggestions[], max
repeatRepeatable sub-formfields[], min, max
markdownRead-only markdowncontent
fileuploadFile uploadaccept, max_bytes
diffapprovalDiff review + approvediff, approve_label, reject_label
colorColor pickerdefault (hex)
moneyCurrency inputcurrency (default "USD"), min, max
percentagePercentage slidermin (0), max (100), step (1)
computedComputed read-onlyexpression

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".

OperatorDescription
eqEqual
neqNot equal
gtGreater than
ltLess than
containsString contains
emptyValue is null or empty
not_emptyValue 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"