{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/linkbreakers-com/json-schema/linkbreakers-com-workflow-steps-service-create-body-schema.json",
  "title": "Request to create a new workflow step",
  "x-generated": "2026-10-30",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/linkbreakers-com-openapi.json#/components/schemas/WorkflowStepsServiceCreateBody",
  "properties": {
    "attributeCapture": {
      "$ref": "#/$defs/AttributeCapture",
      "description": "What the step saves to the visitor's profile (optional)."
    },
    "backButton": {
      "$ref": "#/$defs/BackButton",
      "description": "The page's optional back button, which returns the visitor to the\nprevious page (such as the menu) without wiring a connection. Page steps\nonly: MESSAGE_PAGE, MULTI_LINK, CONTACT_CARD, SOCIAL_LINKS_PAGE,\nFORM_SUBMIT, PASSWORD_VERIFY and THANK_YOU_PAGE. Hidden right after a scan."
    },
    "canvasPosition": {
      "$ref": "#/$defs/CanvasPosition",
      "title": "Canvas position for React Flow visualization (optional)"
    },
    "eventAction": {
      "description": "- EVENT_ACTION_UNSPECIFIED: Event action not specified\n - EVENT_ACTION_CLIENT_REDIRECT: Redirect visitors to a destination URL\n - EVENT_ACTION_LINK_VISIT: Entry step triggered when the link is visited.\n - EVENT_ACTION_PASSWORD_VERIFY: Require visitors to enter a password before proceeding\n - EVENT_ACTION_FORM_SUBMIT: Present a data collection form to visitors\n - EVENT_ACTION_CONTACT_CARD: Generate a vCard (VCF) response with contact information\n - EVENT_ACTION_MULTI_LINK: A page of buttons where each one continues into more workflow: the button\nleads to a next step, not straight out. Records which button the visitor\npressed, so use it over SOCIAL_LINKS_PAGE when that choice is worth\nmeasuring or when a branch needs to do more than redirect. This is the\nmenu step: for several documents or PDFs, give each one a button\nconnected to an OPEN_MEDIA step for media uploaded to the media library, or to\na CLIENT_REDIRECT when the document is already hosted at a URL.\n - EVENT_ACTION_VISIT_TYPE_CONDITION: Route visitors based on whether it's a first or returning visit\n - EVENT_ACTION_COUNTRY_CONDITION: Route visitors based on their country location\n - EVENT_ACTION_DAY_OF_WEEK_CONDITION: Route visitors based on day of week\n - EVENT_ACTION_TIME_OF_DAY_CONDITION: Route visitors based on time of day\n - EVENT_ACTION_DAY_OF_MONTH_CONDITION: Route visitors based on day of month\n - EVENT_ACTION_SPECIFIC_DATE_CONDITION: Route visitors based on specific calendar dates\n - EVENT_ACTION_SOCIAL_LINKS_PAGE: A page of buttons that each leave for an external URL. Social profiles are\nthe common case, not the only one: app stores, docs, booking pages and\nstorefronts all work, and the name is the only thing about it that is\nsocial. It is an exit step, so the visitor leaves from here.\n - EVENT_ACTION_DEVICE_TYPE_CONDITION: Route visitors based on device type (e.g. MOBILE, DESKTOP, TABLET)\n - EVENT_ACTION_DEVICE_PLATFORM_CONDITION: Route visitors based on device platform / operating system (e.g. iOS, Android, macOS)\n - EVENT_ACTION_DEVICE_BROWSER_CONDITION: Route visitors based on browser family (e.g. Chrome, Safari, Firefox)\n - EVENT_ACTION_DEVICE_BRAND_CONDITION: Route visitors based on hardware brand (e.g. Apple, Samsung, Google)\n - EVENT_ACTION_DEVICE_ACTOR_CONDITION: Route visitors based on actor classification: HUMAN, BOT, AGENT, AUTOMATED\nor UNKNOWN. AGENT is an AI agent that names itself (GPTBot, Claude-User,\nPerplexity-User...). AUTOMATED is a browser driven by software, whoever is\nbehind it: headless Chrome from its request, and a visible browser under\nautomation once a link with the Advanced data collection level has read\nnavigator.webdriver, from that device's next visit on.\n - EVENT_ACTION_VISITOR_DATA_CONDITION: Route visitors based on their profile data or custom attributes\n - EVENT_ACTION_THANK_YOU_PAGE: Display a final thank you / completion message (exit step)\n - EVENT_ACTION_MESSAGE_PAGE: Text with ONE way onward: a single button, or a timer that moves the\nvisitor automatically. It carries no list of destinations, so a page that\nshould offer a choice between two or more places is not this step. Use\nSOCIAL_LINKS_PAGE when the choices leave for external URLs, or MULTI_LINK\nwhen each choice continues into more workflow. Never put links, documents\nor PDFs on it: it is a message, nothing else.\n - EVENT_ACTION_OPEN_MEDIA: Hand the visitor one piece of uploaded media, opened in their browser (exit step): a PDF,\nan image (PNG, JPEG, WebP, SVG) or an MP4 video. The visitor is sent straight to the media,\nwith no page of its own. Any media of the library can be opened: it is uploaded once and\nreferenced by its media_id; swapping it means pointing the step at another media item,\nand the QR code never changes.\n - EVENT_ACTION_LOCATION_REQUEST: Ask the visitor for their precise location (GPS) through the browser, with\ntheir permission (composite: two branches, \"location\" when it was shared,\n\"else\" when it was refused, skipped or is unavailable).",
      "enum": [
        "EVENT_ACTION_UNSPECIFIED",
        "EVENT_ACTION_CLIENT_REDIRECT",
        "EVENT_ACTION_LINK_VISIT",
        "EVENT_ACTION_PASSWORD_VERIFY",
        "EVENT_ACTION_FORM_SUBMIT",
        "EVENT_ACTION_CONTACT_CARD",
        "EVENT_ACTION_MULTI_LINK",
        "EVENT_ACTION_VISIT_TYPE_CONDITION",
        "EVENT_ACTION_COUNTRY_CONDITION",
        "EVENT_ACTION_DAY_OF_WEEK_CONDITION",
        "EVENT_ACTION_TIME_OF_DAY_CONDITION",
        "EVENT_ACTION_DAY_OF_MONTH_CONDITION",
        "EVENT_ACTION_SPECIFIC_DATE_CONDITION",
        "EVENT_ACTION_SOCIAL_LINKS_PAGE",
        "EVENT_ACTION_DEVICE_TYPE_CONDITION",
        "EVENT_ACTION_DEVICE_PLATFORM_CONDITION",
        "EVENT_ACTION_DEVICE_BROWSER_CONDITION",
        "EVENT_ACTION_DEVICE_BRAND_CONDITION",
        "EVENT_ACTION_DEVICE_ACTOR_CONDITION",
        "EVENT_ACTION_VISITOR_DATA_CONDITION",
        "EVENT_ACTION_THANK_YOU_PAGE",
        "EVENT_ACTION_MESSAGE_PAGE",
        "EVENT_ACTION_OPEN_MEDIA",
        "EVENT_ACTION_LOCATION_REQUEST"
      ],
      "title": "The event action type for this workflow step"
    },
    "id": {
      "title": "Optional ID for the workflow step (UUID; if not provided, will be generated by backend)",
      "type": "string"
    },
    "insertBefore": {
      "description": "Inserts the new step in front of this one: every branch that led to it\nnow leads to the new step, and the new step's \"next\" branch leads on to\nit. Saves creating and then connecting each side by hand.",
      "type": "string"
    },
    "payload": {
      "$ref": "#/$defs/WorkflowStepPayload",
      "title": "The payload for the workflow step (structure varies by event action)"
    }
  },
  "type": "object",
  "$defs": {
    "AttributeCapture": {
      "description": "A step's opt-in to save values to the visitor's profile, so a workflow can\nrecord qualification without a form: a tapped choice, a milestone reached,\nor the context of the link that was scanned.\n\nAvailable on every step except conditions, which only route on what is\nalready known. A failed password attempt or a skipped form saves nothing.\nOn forms it saves on top of the answers, which forms already save.",
      "properties": {
        "enabled": {
          "description": "Off keeps the configured writes without running them.",
          "type": "boolean"
        },
        "writes": {
          "description": "Up to 20 values to save. Each runs when the visitor goes through the step.",
          "items": {
            "$ref": "#/$defs/AttributeWrite",
            "type": "object"
          },
          "type": "array"
        }
      },
      "type": "object"
    },
    "AttributeWrite": {
      "description": "One value saved to the visitor's profile.",
      "properties": {
        "key": {
          "description": "The attribute key, such as \"looking_for\" or \"book_a_viewing_at\". Letters,\ndigits, \"_\", \"-\" and \".\"; keys starting with \"$\" are reserved.",
          "type": "string"
        },
        "mode": {
          "description": " - ATTRIBUTE_WRITE_MODE_SET: Overwrite, so the profile holds the latest value.\n - ATTRIBUTE_WRITE_MODE_SET_ONCE: Keep the first value, for first-touch facts.",
          "enum": [
            "ATTRIBUTE_WRITE_MODE_UNSPECIFIED",
            "ATTRIBUTE_WRITE_MODE_SET",
            "ATTRIBUTE_WRITE_MODE_SET_ONCE"
          ]
        },
        "type": {
          "description": "VisitorAttributeType is what a value was captured as. It decides how the\nvalue is parsed and which analytics the key can support, which the value\nalone cannot tell you: \"8\" from a rating field and \"8\" typed into a text box\nare different facts.",
          "enum": [
            "VISITOR_ATTRIBUTE_TYPE_UNSPECIFIED",
            "VISITOR_ATTRIBUTE_TYPE_STRING",
            "VISITOR_ATTRIBUTE_TYPE_NUMBER",
            "VISITOR_ATTRIBUTE_TYPE_BOOLEAN",
            "VISITOR_ATTRIBUTE_TYPE_DATE",
            "VISITOR_ATTRIBUTE_TYPE_ENUM"
          ]
        },
        "value": {
          "description": "Literal text, or a template filled in when the visitor goes through the\nstep: {{now}}, {{link.name}}, {{link.metadata.<key>}}, and on MULTI_LINK\nsteps {{choice.label}} and {{choice.id}} for the button tapped. A write\nwhose value comes out empty is skipped.",
          "type": "string"
        }
      },
      "type": "object"
    },
    "BackButton": {
      "description": "A page step's optional back button: a secondary button under the page's\nmain actions that returns the visitor to the previous page in their\nbrowser, exactly like the browser's own back button. Use it for \"Back to\nmenu\" on a sub-page reached from a MULTI_LINK menu instead of wiring a\nconnection back to the menu.\n\nIt hides itself when there is no previous page in the journey, such as on\nthe first page right after a scan, and it never shows on a step whose\nback_button_available is false. Available on page steps only:\nMESSAGE_PAGE, MULTI_LINK, CONTACT_CARD, SOCIAL_LINKS_PAGE, FORM_SUBMIT,\nPASSWORD_VERIFY and THANK_YOU_PAGE. It is not part of the step's payload:\nset it with the back_button field of workflow_steps_create or\nworkflow_steps_update.",
      "properties": {
        "enabled": {
          "description": "Shows the button. Off keeps the label for when it is switched back on.",
          "type": "boolean"
        },
        "label": {
          "description": "Text on the button, up to 40 characters. Defaults to \"Back\".",
          "type": "string"
        }
      },
      "type": "object"
    },
    "CanvasPosition": {
      "properties": {
        "x": {
          "format": "double",
          "title": "X coordinate on the canvas",
          "type": "number"
        },
        "y": {
          "format": "double",
          "title": "Y coordinate on the canvas",
          "type": "number"
        }
      },
      "title": "Canvas position for React Flow node positioning",
      "type": "object"
    },
    "ClientRedirectPayload": {
      "properties": {
        "conversionTracking": {
          "title": "Controls whether lbid is preserved in redirect URL",
          "type": "boolean"
        },
        "destination": {
          "title": "Fully qualified URL used for the redirect",
          "type": "string"
        }
      },
      "title": "Client redirect payload for EVENT_ACTION_CLIENT_REDIRECT",
      "type": "object"
    },
    "CountryConditionOutcome": {
      "properties": {
        "countryCode": {
          "title": "ISO 3166-1 alpha-2 country code (e.g., \"US\", \"FR\", \"GB\")",
          "type": "string"
        },
        "nextStepId": {
          "title": "Workflow step ID to route to for this country (UUID)",
          "type": "string"
        }
      },
      "title": "Country condition outcome definition for EVENT_ACTION_COUNTRY_CONDITION",
      "type": "object"
    },
    "CountryConditionPayload": {
      "properties": {
        "countries": {
          "items": {
            "$ref": "#/$defs/CountryConditionOutcome",
            "type": "object"
          },
          "title": "Country routing configuration",
          "type": "array"
        },
        "elseNextStepId": {
          "title": "Workflow step ID to route to if country doesn't match any configured options (UUID)",
          "type": "string"
        }
      },
      "title": "Country condition payload for EVENT_ACTION_COUNTRY_CONDITION",
      "type": "object"
    },
    "DayOfMonthConditionPayload": {
      "properties": {
        "elseNextStepId": {
          "title": "Workflow step ID to route to if no options match (UUID)",
          "type": "string"
        },
        "options": {
          "items": {
            "$ref": "#/$defs/DayOfMonthOption",
            "type": "object"
          },
          "title": "Day of month routing options",
          "type": "array"
        }
      },
      "title": "Day of month condition payload for EVENT_ACTION_DAY_OF_MONTH_CONDITION",
      "type": "object"
    },
    "DayOfMonthOption": {
      "properties": {
        "dayOfMonth": {
          "description": "Day of month (1-31, or -1 for last day)",
          "format": "int32",
          "title": "Day of month (1-31, or -1 for last day of month)",
          "type": "integer"
        },
        "id": {
          "title": "Unique identifier for this option",
          "type": "string"
        },
        "name": {
          "title": "Optional friendly name for this option",
          "type": "string"
        },
        "nextStepId": {
          "title": "Workflow step ID to route to when this option matches (UUID)",
          "type": "string"
        }
      },
      "title": "Day of month option for EVENT_ACTION_DAY_OF_MONTH_CONDITION",
      "type": "object"
    },
    "DayOfWeekConditionPayload": {
      "properties": {
        "elseNextStepId": {
          "title": "Workflow step ID to route to if no options match (UUID)",
          "type": "string"
        },
        "options": {
          "items": {
            "$ref": "#/$defs/DayOfWeekOption",
            "type": "object"
          },
          "title": "Day of week routing options",
          "type": "array"
        }
      },
      "title": "Day of week condition payload for EVENT_ACTION_DAY_OF_WEEK_CONDITION",
      "type": "object"
    },
    "DayOfWeekOption": {
      "properties": {
        "daysOfWeek": {
          "description": "Days of the week: 0=Sunday, 1=Monday, 2=Tuesday, 3=Wednesday, 4=Thursday, 5=Friday, 6=Saturday",
          "items": {
            "format": "int32",
            "type": "integer"
          },
          "title": "Days of week (0=Sunday, 1=Monday, ..., 6=Saturday)",
          "type": "array"
        },
        "id": {
          "title": "Unique identifier for this option",
          "type": "string"
        },
        "name": {
          "title": "Optional friendly name for this option",
          "type": "string"
        },
        "nextStepId": {
          "title": "Workflow step ID to route to when this option matches (UUID)",
          "type": "string"
        }
      },
      "title": "Day of week option for EVENT_ACTION_DAY_OF_WEEK_CONDITION",
      "type": "object"
    },
    "DeviceActorConditionOption": {
      "description": "Device actor condition option for EVENT_ACTION_DEVICE_ACTOR_CONDITION.",
      "properties": {
        "id": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "nextStepId": {
          "type": "string"
        },
        "value": {
          "description": "Allowed values for device actor routing conditions.",
          "enum": [
            "DEVICE_ACTOR_CONDITION_VALUE_UNSPECIFIED",
            "DEVICE_ACTOR_CONDITION_VALUE_HUMAN",
            "DEVICE_ACTOR_CONDITION_VALUE_BOT",
            "DEVICE_ACTOR_CONDITION_VALUE_AGENT",
            "DEVICE_ACTOR_CONDITION_VALUE_UNKNOWN",
            "DEVICE_ACTOR_CONDITION_VALUE_AUTOMATED"
          ]
        }
      },
      "type": "object"
    },
    "DeviceActorConditionPayload": {
      "description": "Device actor condition payload for EVENT_ACTION_DEVICE_ACTOR_CONDITION. An\nAGENT option matches AI agents that name themselves. An AUTOMATED option\nmatches headless browsers on every visit, and a visible browser under\nautomation from its second visit, once the link collects data at the\nAdvanced level, which lets the page read navigator.webdriver. To treat both\nthe same, route AGENT and AUTOMATED to the same step.",
      "properties": {
        "elseNextStepId": {
          "type": "string"
        },
        "options": {
          "items": {
            "$ref": "#/$defs/DeviceActorConditionOption",
            "type": "object"
          },
          "type": "array"
        }
      },
      "type": "object"
    },
    "DeviceBrandConditionOption": {
      "description": "Device brand condition option for EVENT_ACTION_DEVICE_BRAND_CONDITION.",
      "properties": {
        "id": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "nextStepId": {
          "type": "string"
        },
        "value": {
          "description": "Allowed values for device brand routing conditions.",
          "enum": [
            "DEVICE_BRAND_CONDITION_VALUE_UNSPECIFIED",
            "DEVICE_BRAND_CONDITION_VALUE_APPLE",
            "DEVICE_BRAND_CONDITION_VALUE_SAMSUNG",
            "DEVICE_BRAND_CONDITION_VALUE_GOOGLE",
            "DEVICE_BRAND_CONDITION_VALUE_HUAWEI",
            "DEVICE_BRAND_CONDITION_VALUE_XIAOMI",
            "DEVICE_BRAND_CONDITION_VALUE_ONEPLUS"
          ]
        }
      },
      "type": "object"
    },
    "DeviceBrandConditionPayload": {
      "properties": {
        "elseNextStepId": {
          "type": "string"
        },
        "options": {
          "items": {
            "$ref": "#/$defs/DeviceBrandConditionOption",
            "type": "object"
          },
          "type": "array"
        }
      },
      "type": "object"
    },
    "DeviceBrowserConditionOption": {
      "description": "Device browser condition option for EVENT_ACTION_DEVICE_BROWSER_CONDITION.",
      "properties": {
        "id": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "nextStepId": {
          "type": "string"
        },
        "value": {
          "description": "Allowed values for device browser routing conditions.",
          "enum": [
            "DEVICE_BROWSER_CONDITION_VALUE_UNSPECIFIED",
            "DEVICE_BROWSER_CONDITION_VALUE_CHROME",
            "DEVICE_BROWSER_CONDITION_VALUE_SAFARI",
            "DEVICE_BROWSER_CONDITION_VALUE_FIREFOX",
            "DEVICE_BROWSER_CONDITION_VALUE_EDGE",
            "DEVICE_BROWSER_CONDITION_VALUE_OPERA",
            "DEVICE_BROWSER_CONDITION_VALUE_SAMSUNG_BROWSER"
          ]
        }
      },
      "type": "object"
    },
    "DeviceBrowserConditionPayload": {
      "properties": {
        "elseNextStepId": {
          "type": "string"
        },
        "options": {
          "items": {
            "$ref": "#/$defs/DeviceBrowserConditionOption",
            "type": "object"
          },
          "type": "array"
        }
      },
      "type": "object"
    },
    "DevicePlatformConditionOption": {
      "description": "Device platform condition option for EVENT_ACTION_DEVICE_PLATFORM_CONDITION.",
      "properties": {
        "id": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "nextStepId": {
          "type": "string"
        },
        "value": {
          "description": "Allowed values for device platform routing conditions.",
          "enum": [
            "DEVICE_PLATFORM_CONDITION_VALUE_UNSPECIFIED",
            "DEVICE_PLATFORM_CONDITION_VALUE_IOS",
            "DEVICE_PLATFORM_CONDITION_VALUE_ANDROID",
            "DEVICE_PLATFORM_CONDITION_VALUE_WINDOWS",
            "DEVICE_PLATFORM_CONDITION_VALUE_MACOS",
            "DEVICE_PLATFORM_CONDITION_VALUE_LINUX",
            "DEVICE_PLATFORM_CONDITION_VALUE_CHROMEOS"
          ]
        }
      },
      "type": "object"
    },
    "DevicePlatformConditionPayload": {
      "properties": {
        "elseNextStepId": {
          "type": "string"
        },
        "options": {
          "items": {
            "$ref": "#/$defs/DevicePlatformConditionOption",
            "type": "object"
          },
          "type": "array"
        }
      },
      "type": "object"
    },
    "DeviceTypeConditionOption": {
      "description": "Device type condition option for EVENT_ACTION_DEVICE_TYPE_CONDITION.",
      "properties": {
        "id": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "nextStepId": {
          "type": "string"
        },
        "value": {
          "description": "Allowed values for device type routing conditions.",
          "enum": [
            "DEVICE_TYPE_CONDITION_VALUE_UNSPECIFIED",
            "DEVICE_TYPE_CONDITION_VALUE_MOBILE",
            "DEVICE_TYPE_CONDITION_VALUE_DESKTOP",
            "DEVICE_TYPE_CONDITION_VALUE_TABLET",
            "DEVICE_TYPE_CONDITION_VALUE_UNKNOWN"
          ]
        }
      },
      "type": "object"
    },
    "DeviceTypeConditionPayload": {
      "properties": {
        "elseNextStepId": {
          "type": "string"
        },
        "options": {
          "items": {
            "$ref": "#/$defs/DeviceTypeConditionOption",
            "type": "object"
          },
          "type": "array"
        }
      },
      "type": "object"
    },
    "FormField": {
      "properties": {
        "defaultValue": {
          "title": "Value pre-filled when the form renders",
          "type": "string"
        },
        "helpText": {
          "title": "Helper copy displayed under the input",
          "type": "string"
        },
        "id": {
          "title": "Unique identifier for this field within the form",
          "type": "string"
        },
        "key": {
          "title": "Field key for data storage (maps to visitor attributes or system fields like $email)",
          "type": "string"
        },
        "label": {
          "title": "Display label for the field",
          "type": "string"
        },
        "options": {
          "items": {
            "$ref": "#/$defs/FormFieldOption",
            "type": "object"
          },
          "title": "Options for radio, checkbox, or select fields",
          "type": "array"
        },
        "order": {
          "format": "int32",
          "title": "Display order (for drag-and-drop reordering)",
          "type": "integer"
        },
        "placeholder": {
          "title": "Placeholder text",
          "type": "string"
        },
        "required": {
          "title": "Whether this field is required",
          "type": "boolean"
        },
        "type": {
          "description": "- FORM_FIELD_TYPE_UNSPECIFIED: Form field type not specified",
          "enum": [
            "FORM_FIELD_TYPE_UNSPECIFIED",
            "FORM_FIELD_TYPE_TEXT",
            "FORM_FIELD_TYPE_EMAIL",
            "FORM_FIELD_TYPE_PHONE",
            "FORM_FIELD_TYPE_TEXTAREA",
            "FORM_FIELD_TYPE_RADIO",
            "FORM_FIELD_TYPE_CHECKBOX",
            "FORM_FIELD_TYPE_DROPDOWN",
            "FORM_FIELD_TYPE_NUMBER",
            "FORM_FIELD_TYPE_DATE",
            "FORM_FIELD_TYPE_RATING"
          ],
          "title": "Field type (text, email, radio, etc.)"
        },
        "validationPattern": {
          "title": "Additional field-specific configuration\nOptional regex applied client-side to validate the field value",
          "type": "string"
        }
      },
      "title": "Form field definition for FORM_SUBMIT event action",
      "type": "object"
    },
    "FormFieldOption": {
      "properties": {
        "label": {
          "title": "Human-readable label presented to members",
          "type": "string"
        },
        "value": {
          "title": "Value stored when the option is selected",
          "type": "string"
        }
      },
      "title": "Option for radio, checkbox, or select fields",
      "type": "object"
    },
    "FormPayload": {
      "properties": {
        "autoSkipIfKnown": {
          "title": "Automatically skip the form when required data is already known",
          "type": "boolean"
        },
        "formDescription": {
          "title": "Body copy rendered above the form fields",
          "type": "string"
        },
        "formFields": {
          "items": {
            "$ref": "#/$defs/FormField",
            "type": "object"
          },
          "title": "Form fields to present to visitors",
          "type": "array"
        },
        "formTitle": {
          "title": "Optional heading shown on the visitor form",
          "type": "string"
        },
        "skipButtonText": {
          "title": "Custom text for the skip button (defaults to \"Skip for now\" when skip_form is enabled)",
          "type": "string"
        },
        "skipForm": {
          "title": "Whether the visitor experience should offer a \"Skip\" option and record an empty submission",
          "type": "boolean"
        },
        "submitButtonText": {
          "title": "Custom text for the submit button (defaults to \"Submit\")",
          "type": "string"
        }
      },
      "title": "Form data collection payload for EVENT_ACTION_FORM_SUBMIT",
      "type": "object"
    },
    "LinkVisitPayload": {
      "description": "Reserved for future link visit specific configuration",
      "title": "Entry payload for EVENT_ACTION_LINK_VISIT (currently no specific fields)",
      "type": "object"
    },
    "LocationRequestPayload": {
      "properties": {
        "askOnce": {
          "title": "Ask only once per device: a device that already shared its location on\nthis step passes over it on later visits, taking the \"location\" branch",
          "type": "boolean"
        },
        "buttonLabel": {
          "title": "Label of the button that triggers the browser's location prompt",
          "type": "string"
        },
        "description": {
          "title": "Text under the heading, saying why the location is asked for",
          "type": "string"
        },
        "elseNextStepId": {
          "title": "Step the visitor goes to when the location is refused, skipped or\nunavailable (\"else\" branch)",
          "type": "string"
        },
        "nextStepId": {
          "title": "Step the visitor goes to once the location is shared (\"location\" branch)",
          "type": "string"
        },
        "skipEnabled": {
          "title": "Whether the page offers a skip button, which takes the \"else\" branch\nwithout triggering the browser prompt",
          "type": "boolean"
        },
        "skipLabel": {
          "title": "Label of the skip button",
          "type": "string"
        },
        "title": {
          "title": "Heading shown on the page",
          "type": "string"
        }
      },
      "title": "Location request payload for EVENT_ACTION_LOCATION_REQUEST",
      "type": "object"
    },
    "MessagePagePayload": {
      "properties": {
        "buttonLabel": {
          "title": "Label for the navigation button (only used when navigation_type is BUTTON, defaults to \"Continue\")",
          "type": "string"
        },
        "description": {
          "title": "Optional descriptive text below the title",
          "type": "string"
        },
        "navigationType": {
          "description": "- MESSAGE_PAGE_NAVIGATION_TYPE_UNSPECIFIED: Navigation type not specified\n - MESSAGE_PAGE_NAVIGATION_TYPE_BUTTON: Visitor clicks a button to proceed\n - MESSAGE_PAGE_NAVIGATION_TYPE_TIMER: Visitor is automatically redirected after a timer expires",
          "enum": [
            "MESSAGE_PAGE_NAVIGATION_TYPE_UNSPECIFIED",
            "MESSAGE_PAGE_NAVIGATION_TYPE_BUTTON",
            "MESSAGE_PAGE_NAVIGATION_TYPE_TIMER"
          ],
          "title": "How the visitor proceeds to the next step"
        },
        "timerSeconds": {
          "format": "int32",
          "title": "Seconds before auto-redirect (only used when navigation_type is TIMER)",
          "type": "integer"
        },
        "title": {
          "title": "The main heading displayed on the message page",
          "type": "string"
        }
      },
      "required": [
        "title",
        "navigationType"
      ],
      "title": "MessagePagePayload is a mid-flow informational page with mandatory navigation",
      "type": "object"
    },
    "MultiLinkButton": {
      "properties": {
        "id": {
          "title": "Unique identifier for this button",
          "type": "string"
        },
        "label": {
          "title": "Display label for the button",
          "type": "string"
        },
        "nextStepId": {
          "title": "The ID of the next workflow step to transition to (UUID)",
          "type": "string"
        },
        "order": {
          "format": "int32",
          "title": "Display order for buttons",
          "type": "integer"
        }
      },
      "title": "Button definition for EVENT_ACTION_MULTI_LINK",
      "type": "object"
    },
    "MultiLinkPayload": {
      "properties": {
        "buttons": {
          "items": {
            "$ref": "#/$defs/MultiLinkButton",
            "type": "object"
          },
          "title": "Buttons to display on the multi-link page",
          "type": "array"
        },
        "description": {
          "title": "Optional description displayed on the multi-link page",
          "type": "string"
        },
        "title": {
          "title": "Optional title displayed on the multi-link page",
          "type": "string"
        }
      },
      "title": "Multi-link page payload for EVENT_ACTION_MULTI_LINK",
      "type": "object"
    },
    "OpenMediaPayload": {
      "properties": {
        "mediaId": {
          "description": "The media item (UUID) handed to the visitor: any ready media of the workspace (a PDF, an image or an MP4 video).",
          "type": "string"
        }
      },
      "required": [
        "mediaId"
      ],
      "title": "OpenMediaPayload hands the visitor one piece of media from the media library (EVENT_ACTION_OPEN_MEDIA)",
      "type": "object"
    },
    "PasswordPayload": {
      "properties": {
        "description": {
          "title": "Additional helper copy displayed under the password prompt",
          "type": "string"
        },
        "password": {
          "title": "Plaintext password visitors must enter to continue the workflow",
          "type": "string"
        },
        "title": {
          "title": "Heading shown above the password prompt",
          "type": "string"
        }
      },
      "title": "Password protection payload for EVENT_ACTION_PASSWORD_VERIFY",
      "type": "object"
    },
    "SocialLinkButton": {
      "properties": {
        "id": {
          "title": "Unique identifier for this link",
          "type": "string"
        },
        "order": {
          "format": "int32",
          "title": "Display order for links (order 1 will be highlighted)",
          "type": "integer"
        },
        "platform": {
          "title": "Platform identifier picking the icon. Leave it empty and the API names it\nfrom the URL, which is what you normally want. Known values: appstore,\nplaystore, instagram, tiktok, twitter, facebook, youtube, linkedin,\ngithub, medium, whatsapp, telegram, discord, slack, spotify, applemusic,\ntwitch, snapchat, pinterest, reddit, calendly, website.\nSupported platforms: instagram, tiktok, twitter, facebook, website, youtube, linkedin, github, whatsapp",
          "type": "string"
        },
        "url": {
          "title": "Destination URL for the link",
          "type": "string"
        }
      },
      "title": "Social link button definition for EVENT_ACTION_SOCIAL_LINKS_PAGE",
      "type": "object"
    },
    "SocialLinksPayload": {
      "properties": {
        "description": {
          "title": "Optional description displayed on the social links page",
          "type": "string"
        },
        "displayStyle": {
          "description": "- SOCIAL_LINKS_DISPLAY_STYLE_DETAILED: Display icon with text label (default)\n - SOCIAL_LINKS_DISPLAY_STYLE_COMPACT: Display icons only in a compact row",
          "enum": [
            "SOCIAL_LINKS_DISPLAY_STYLE_UNSPECIFIED",
            "SOCIAL_LINKS_DISPLAY_STYLE_DETAILED",
            "SOCIAL_LINKS_DISPLAY_STYLE_COMPACT"
          ],
          "title": "Display style for the social links (defaults to detailed if not specified)"
        },
        "links": {
          "items": {
            "$ref": "#/$defs/SocialLinkButton",
            "type": "object"
          },
          "title": "Social links to display (up to 10)",
          "type": "array"
        },
        "title": {
          "title": "Optional title displayed on the social links page",
          "type": "string"
        }
      },
      "title": "Social links page payload for EVENT_ACTION_SOCIAL_LINKS_PAGE",
      "type": "object"
    },
    "SpecificDateConditionPayload": {
      "properties": {
        "elseNextStepId": {
          "title": "Workflow step ID to route to if no options match (UUID)",
          "type": "string"
        },
        "options": {
          "items": {
            "$ref": "#/$defs/SpecificDateOption",
            "type": "object"
          },
          "title": "Specific date routing options",
          "type": "array"
        }
      },
      "title": "Specific date condition payload for EVENT_ACTION_SPECIFIC_DATE_CONDITION",
      "type": "object"
    },
    "SpecificDateOption": {
      "properties": {
        "day": {
          "description": "Day of month (1-31)",
          "format": "int32",
          "title": "Day of month (1-31)",
          "type": "integer"
        },
        "id": {
          "title": "Unique identifier for this option",
          "type": "string"
        },
        "month": {
          "description": "Month (1-12)",
          "format": "int32",
          "title": "Month (1-12)",
          "type": "integer"
        },
        "name": {
          "title": "Optional friendly name for this option",
          "type": "string"
        },
        "nextStepId": {
          "title": "Workflow step ID to route to when this option matches (UUID)",
          "type": "string"
        },
        "year": {
          "description": "Year (optional, for one-time dates)",
          "format": "int32",
          "title": "Optional year for one-time events",
          "type": "integer"
        }
      },
      "title": "Specific date option for EVENT_ACTION_SPECIFIC_DATE_CONDITION",
      "type": "object"
    },
    "ThankYouPagePayload": {
      "properties": {
        "description": {
          "title": "Optional descriptive text below the title",
          "type": "string"
        },
        "title": {
          "title": "The main heading displayed on the thank you page",
          "type": "string"
        }
      },
      "required": [
        "title"
      ],
      "title": "ThankYouPagePayload is a terminal exit page displaying a title and optional description",
      "type": "object"
    },
    "TimeOfDayConditionPayload": {
      "properties": {
        "elseNextStepId": {
          "title": "Workflow step ID to route to if no ranges match (UUID)",
          "type": "string"
        },
        "ranges": {
          "items": {
            "$ref": "#/$defs/TimeOfDayRange",
            "type": "object"
          },
          "title": "Time range routing options",
          "type": "array"
        }
      },
      "title": "Time of day condition payload for EVENT_ACTION_TIME_OF_DAY_CONDITION",
      "type": "object"
    },
    "TimeOfDayRange": {
      "properties": {
        "endTime": {
          "description": "End time in 24-hour format (HH:MM)",
          "title": "End time in 24-hour format (HH:MM)",
          "type": "string"
        },
        "id": {
          "title": "Unique identifier for this range",
          "type": "string"
        },
        "name": {
          "title": "Optional friendly name for this range",
          "type": "string"
        },
        "nextStepId": {
          "title": "Workflow step ID to route to when this range matches (UUID)",
          "type": "string"
        },
        "startTime": {
          "description": "Start time in 24-hour format (HH:MM)",
          "title": "Start time in 24-hour format (HH:MM)",
          "type": "string"
        }
      },
      "title": "Time of day range for EVENT_ACTION_TIME_OF_DAY_CONDITION",
      "type": "object"
    },
    "VCardPayload": {
      "properties": {
        "buttonLabel": {
          "title": "Label displayed on the contact button",
          "type": "string"
        },
        "city": {
          "title": "City for the vCard address",
          "type": "string"
        },
        "country": {
          "title": "Country for the vCard address",
          "type": "string"
        },
        "email": {
          "title": "Email address for the vCard",
          "type": "string"
        },
        "firstName": {
          "title": "First name for the vCard",
          "type": "string"
        },
        "lastName": {
          "title": "Last name for the vCard",
          "type": "string"
        },
        "organization": {
          "title": "Organization/company name for the vCard",
          "type": "string"
        },
        "phone": {
          "title": "Phone number for the vCard",
          "type": "string"
        },
        "phoneIsWhatsapp": {
          "title": "Whether the phone number is also a WhatsApp number (shows WhatsApp link on contact card)",
          "type": "boolean"
        },
        "phoneSmsEnabled": {
          "title": "Whether visitors can also text the phone number (shows a \"Send a text\" action that opens the SMS app)",
          "type": "boolean"
        },
        "postalCode": {
          "title": "Postal/ZIP code for the vCard address",
          "type": "string"
        },
        "saveButtonEnabled": {
          "description": "Whether the card shows its save button (\"Add to contacts\"). Defaults to true when unset.",
          "type": "boolean"
        },
        "socialLinks": {
          "items": {
            "$ref": "#/$defs/VCardSocialLink",
            "type": "object"
          },
          "title": "Optional social links to display on the contact card and embed in the vCard",
          "type": "array"
        },
        "state": {
          "title": "State/province for the vCard address",
          "type": "string"
        },
        "streetAddress": {
          "title": "Street address for the vCard",
          "type": "string"
        },
        "title": {
          "title": "Job title for the vCard",
          "type": "string"
        },
        "website": {
          "title": "Website URL for the vCard",
          "type": "string"
        }
      },
      "title": "vCard payload for EVENT_ACTION_CONTACT_CARD",
      "type": "object"
    },
    "VCardSocialLink": {
      "properties": {
        "platform": {
          "description": "Platform identifier picking the icon. Leave it empty and the API names it\nfrom the URL, which is what you normally want. Known values: appstore,\nplaystore, instagram, tiktok, twitter, facebook, youtube, linkedin,\ngithub, medium, whatsapp, telegram, discord, slack, spotify, applemusic,\ntwitch, snapchat, pinterest, reddit, calendly, website.",
          "type": "string"
        },
        "url": {
          "title": "Profile URL for this social platform",
          "type": "string"
        }
      },
      "title": "Social link entry for a vCard contact card",
      "type": "object"
    },
    "VisitTypeConditionOption": {
      "properties": {
        "nextStepId": {
          "title": "Workflow step ID to route to for this visit type (UUID)",
          "type": "string"
        },
        "value": {
          "title": "Visit type value to match (e.g. FIRST, RETURNING)",
          "type": "string"
        }
      },
      "type": "object"
    },
    "VisitTypeConditionPayload": {
      "properties": {
        "elseNextStepId": {
          "title": "Workflow step ID to route to if the visit type does not match any configured options (UUID)",
          "type": "string"
        },
        "options": {
          "items": {
            "$ref": "#/$defs/VisitTypeConditionOption",
            "type": "object"
          },
          "title": "Visit type routing options",
          "type": "array"
        }
      },
      "title": "Visit type condition payload for EVENT_ACTION_VISIT_TYPE_CONDITION",
      "type": "object"
    },
    "VisitorDataConditionOption": {
      "description": "Visitor data condition option for EVENT_ACTION_VISITOR_DATA_CONDITION.",
      "properties": {
        "attributeKey": {
          "title": "Visitor attribute key to check (e.g., \"age\", \"$email\", \"company\")",
          "type": "string"
        },
        "comparisonValue": {
          "title": "Value to compare against (optional for operators like IS_EMPTY)",
          "type": "string"
        },
        "id": {
          "type": "string"
        },
        "nextStepId": {
          "type": "string"
        },
        "operator": {
          "title": "Operator for comparison (e.g., \"STRING_EQUALS\", \"NUMBER_GREATER_THAN\", \"DATE_BEFORE\")",
          "type": "string"
        }
      },
      "type": "object"
    },
    "VisitorDataConditionPayload": {
      "properties": {
        "elseNextStepId": {
          "type": "string"
        },
        "options": {
          "items": {
            "$ref": "#/$defs/VisitorDataConditionOption",
            "type": "object"
          },
          "type": "array"
        }
      },
      "type": "object"
    },
    "WorkflowStepPayload": {
      "properties": {
        "clientRedirect": {
          "$ref": "#/$defs/ClientRedirectPayload"
        },
        "countryCondition": {
          "$ref": "#/$defs/CountryConditionPayload"
        },
        "dayOfMonthCondition": {
          "$ref": "#/$defs/DayOfMonthConditionPayload"
        },
        "dayOfWeekCondition": {
          "$ref": "#/$defs/DayOfWeekConditionPayload"
        },
        "deviceActorCondition": {
          "$ref": "#/$defs/DeviceActorConditionPayload"
        },
        "deviceBrandCondition": {
          "$ref": "#/$defs/DeviceBrandConditionPayload"
        },
        "deviceBrowserCondition": {
          "$ref": "#/$defs/DeviceBrowserConditionPayload"
        },
        "devicePlatformCondition": {
          "$ref": "#/$defs/DevicePlatformConditionPayload"
        },
        "deviceTypeCondition": {
          "$ref": "#/$defs/DeviceTypeConditionPayload"
        },
        "form": {
          "$ref": "#/$defs/FormPayload"
        },
        "linkVisit": {
          "$ref": "#/$defs/LinkVisitPayload"
        },
        "locationRequest": {
          "$ref": "#/$defs/LocationRequestPayload"
        },
        "messagePage": {
          "$ref": "#/$defs/MessagePagePayload"
        },
        "multiLink": {
          "$ref": "#/$defs/MultiLinkPayload"
        },
        "openMedia": {
          "$ref": "#/$defs/OpenMediaPayload"
        },
        "password": {
          "$ref": "#/$defs/PasswordPayload"
        },
        "socialLinks": {
          "$ref": "#/$defs/SocialLinksPayload"
        },
        "specificDateCondition": {
          "$ref": "#/$defs/SpecificDateConditionPayload"
        },
        "thankYouPage": {
          "$ref": "#/$defs/ThankYouPagePayload"
        },
        "timeOfDayCondition": {
          "$ref": "#/$defs/TimeOfDayConditionPayload"
        },
        "vcard": {
          "$ref": "#/$defs/VCardPayload"
        },
        "visitTypeCondition": {
          "$ref": "#/$defs/VisitTypeConditionPayload"
        },
        "visitorDataCondition": {
          "$ref": "#/$defs/VisitorDataConditionPayload"
        }
      },
      "title": "Workflow step payload - uses oneof for type safety based on EventAction",
      "type": "object"
    }
  }
}