Rundunrundun

Step types

Rundun supports 11 step types. The type field on a step determines the UI control rendered to the executor and the shape of the answer value stored on the run.

Quick reference

Type Visual control Answer shape
boolean Checkbox / toggle true or false
choice Single-select list "o-fu2" (option ID string)
multi_choice Multi-select list ["o-dm1", "o-dm3"] (array of option IDs)
text Text input or text area "Scratch on rear left door"
number Numeric keypad input 42150
rating Horizontal scale 4 (integer)
photo Camera launcher null (answer is the photos array)
signature Signature pad "https://media.rundun.app/runs/.../sig.png"
instruction Read-only text block null (acknowledged)
barcode Camera in scan mode "VIN1234567890"
datetime Date/time picker "2026-05-10" or "2026-05-10T14:00:00Z"

boolean

A single yes/no toggle. Use for binary decisions. Use choice when there are 3 or more options.

{
  "id": "s-cl01",
  "type": "boolean",
  "label": "Is the unit clean and ready for the next guest?",
  "hint": "Check all rooms, bathroom, and kitchen",
  "required": true,
  "photo": false,
  "geo": false,
  "config": {
    "true_label": "Yes, ready",
    "false_label": "No, needs attention"
  }
}

true_label and false_label are optional. Default to "Yes" / "No".


choice

A single-select list. The answer is the ID of the selected option.

{
  "id": "s-fu01",
  "type": "choice",
  "label": "Fuel level",
  "required": true,
  "photo": false,
  "geo": false,
  "config": {
    "options": [
      { "id": "o-fu1", "label": "Full" },
      { "id": "o-fu2", "label": "3/4" },
      { "id": "o-fu3", "label": "1/2" },
      { "id": "o-fu4", "label": "1/4" },
      { "id": "o-fu5", "label": "Empty" }
    ]
  }
}

The answer value ("o-fu2") is the option ID, not the label. This means you can rename options without breaking existing answers.


multi_choice

A multi-select list. The answer is an array of selected option IDs.

{
  "id": "s-dm02",
  "type": "multi_choice",
  "label": "Damage types found",
  "hint": "Select all that apply",
  "required": true,
  "photo": { "min": 1, "max": 6, "annotate": false },
  "geo": false,
  "config": {
    "options": [
      { "id": "o-dm1", "label": "Scratch" },
      { "id": "o-dm2", "label": "Dent" },
      { "id": "o-dm3", "label": "Crack" },
      { "id": "o-dm4", "label": "Paint chip" }
    ]
  }
}

Answer example: ["o-dm1", "o-dm3"] — scratch and crack were selected.


text

A freeform text input. Use multiline: true for longer responses.

{
  "id": "s-dm03",
  "type": "text",
  "label": "Describe the damage",
  "hint": "Be as specific as possible — include location",
  "required": true,
  "photo": false,
  "geo": false,
  "config": {
    "multiline": true,
    "max_length": 500,
    "placeholder": "e.g. Scratch on rear left door, approx 15cm"
  }
}

max_length is optional. placeholder is hint text shown inside the input when empty.


number

A numeric input rendered with a numeric keypad on mobile.

{
  "id": "s-od01",
  "type": "number",
  "label": "Odometer reading",
  "required": true,
  "photo": false,
  "geo": false,
  "config": {
    "unit": "km",
    "min": 0,
    "max": 999999,
    "decimal": 0
  }
}
Config field Description
unit Label shown after the input (e.g. "km", "$", "%") — optional
min / max Range validation — optional
decimal Number of decimal places allowed. 0 = integers only

rating

A horizontal tap-to-select scale. The answer is an integer.

{
  "id": "s-cl02",
  "type": "rating",
  "label": "Interior cleanliness",
  "required": true,
  "photo": { "min": 0, "max": 3 },
  "geo": false,
  "config": {
    "min": 1,
    "max": 5,
    "low_label": "Very dirty",
    "high_label": "Spotless"
  }
}

low_label and high_label are optional labels displayed at the ends of the scale.


photo

A camera step where the answer itself is one or more photos. Use this when no other answer type is needed.

For adding photos to any other step type (e.g. take a photo after answering a boolean), use the photo overlay field on the step instead — see Photos.

{
  "id": "s-fp01",
  "type": "photo",
  "label": "Front of vehicle",
  "hint": "Take a straight-on shot showing the full front",
  "required": true,
  "photo": false,
  "geo": false,
  "config": {
    "min": 1,
    "max": 3,
    "annotate": false
  }
}

The answer value in webhook payloads is null for photo steps — the photos are in the photos array.


signature

A signature pad rendered on screen. The executor draws their signature. The result is uploaded to Rundun's servers and the URL is stored as the answer.

{
  "id": "s-sg01",
  "type": "signature",
  "label": "Customer signature",
  "hint": "Customer confirms the vehicle condition as documented above",
  "required": true,
  "photo": false,
  "geo": false,
  "config": {}
}

Answer: "https://media.rundun.app/runs/r-550e8400-.../s-sg01/sig.png"


instruction

A read-only text block the executor must acknowledge before proceeding. No answer is captured.

Use for safety warnings, procedural notes, or contextual information between steps.

{
  "id": "s-in01",
  "type": "instruction",
  "label": "Walk around the entire vehicle before starting",
  "hint": "Check all four sides, the roof, and underneath the bumpers",
  "required": false,
  "photo": false,
  "geo": false,
  "config": {}
}

The answer value in webhook payloads is null for instruction steps.


barcode

A camera in scan mode for QR codes and barcodes. The decoded string is stored as the answer.

{
  "id": "s-vin1",
  "type": "barcode",
  "label": "Scan vehicle VIN",
  "hint": "Located on the dashboard, visible through the windshield",
  "required": true,
  "photo": false,
  "geo": false,
  "config": {
    "formats": ["code128", "qr", "code39", "any"]
  }
}

formats is optional. Use "any" to accept all supported formats. Supported values: "qr", "code128", "code39", "ean13", "ean8", "datamatrix", "any".

Answer: "JN1AZ4EH2FM123456" (the decoded barcode value).


datetime

A native date and/or time picker.

{
  "id": "s-rt01",
  "type": "datetime",
  "label": "Expected return date",
  "required": true,
  "photo": false,
  "geo": false,
  "config": {
    "mode": "date",
    "min_offset_hours": 1,
    "max_offset_days": 30
  }
}
Config field Description
mode "date" (date only), "time" (time only), or "datetime" (both)
min_offset_hours Minimum selectable time, expressed as hours from now — optional
max_offset_days Maximum selectable date, expressed as days from now — optional

Answer format:

  • mode: "date""2026-05-22" (ISO 8601 date)
  • mode: "time""14:30" (24-hour HH:MM)
  • mode: "datetime""2026-05-22T14:30:00Z" (ISO 8601 datetime, UTC)

Photo overlay

Any step type (except photo) can require photos in addition to its primary answer. Set the photo field on the step:

{
  "id": "s-dm01",
  "type": "boolean",
  "label": "Any damage to bodywork?",
  "required": true,
  "photo": { "min": 0, "max": 4, "annotate": false },
  "config": { "true_label": "Yes", "false_label": "No" }
}
  • min: 0 — photos are optional
  • min: 1 — at least one photo required before the step can be completed
  • max — maximum photos allowed (1–10)
  • annotate — drawing overlay on photos (post-MVP, always false for now)

photo: false or omitting photo entirely means no camera is shown for that step.

See Photos for the full upload flow and how photos appear in webhook payloads.