Forms

Intro

Endpoint: https://api.omnisend.com/api/forms

Create, configure, enable, and render Omnisend signup forms. A form defines its content (a hierarchical layout of steps, sections, rows, columns, and blocks) and the targeting rules that decide when and to whom it is shown.

New forms are created in draft status and are not shown to visitors until enabled with POST /api/forms/{formID}/enable.

Display types

Each form has a displayType that controls how it is presented to visitors. Choose it based on how prominent and interruptive the signup experience should be.

displayTypeDescription
popupModal centered over the page that dims the background. Highest visibility; best for launch offers, discounts, and exit-intent capture where interrupting the visitor is acceptable.
flyoutCompact panel anchored to a page corner that leaves the page usable. Less intrusive; suited to always-on signup while the visitor keeps browsing.
embeddedRendered inline within the host page's content. Use for a permanent signup block placed in a section, sidebar, or footer rather than an overlay.
landingPageFull standalone page hosted by Omnisend. Use for campaigns driven by ads, emails, or shared links where there is no host site to embed into.
fullscreenOverlay that covers the entire viewport. Maximum attention; best for high-value offers where taking over the screen is justified.

Only popup, flyout and fullscreen forms are eligible for A/B testing (see the Form A/B Setups reference).

Form content structure

A form's content follows a strict hierarchy:

Content
  └── Steps[]            (1–2 screens of the form)
        └── Sections[]
              └── Rows[]
                    └── Columns[]   (up to 4 per row)
                          └── Blocks[]
  • Steps are the screens a visitor moves through (a single-step form has one; multi-step forms have two). content also accepts optional successStep, subscribedStep, and unavailablePageStep screens shown after submission or when the form is unavailable.
  • Sections are top-level content containers within a step, each with its own style properties.
  • Rows group columns horizontally within a section.
  • Columns define layout width (pixels or percent) and contain blocks. A row holds up to four columns.
  • Blocks are the actual content elements (text, image, button, input fields, etc.).

Sections, rows, columns, and blocks each carry a server-generated id that is assigned on create and returned in responses. You may omit these IDs from create/update requests.

content also carries generalSettings — the shared presentation of the form (container width and overlay color, body styling, link color, button/text presets, field styles, and position) — and an optional teaser shown before or after the form.

Block types

Each block's type field selects its content element and the matching configuration object (for example a text block carries text, an image block carries image).

TypeDescription
textRich text content with HTML formatting
imageImage referencing an existing image in the Images API, with optional link and alt text
buttonClickable button (link, submit, close, or nextStep behavior)
lineSpaceDivider line or blank spacer for layout separation
emailFieldEmail input field
phoneNumberFieldPhone number input field with default country code
inputFieldGeneric profile input field (maps to a contact property)
legalLegal consent block (gdpr or tcpa)
dateFieldDate input field
dropdownFieldDropdown selection field
radioFieldRadio selection field
checkboxFieldCheckbox selection field
wheelOfFortuneGamified wheel with configurable slices and win probabilities
discountDiscount code block (wheelOfFortune or static source)
countdownTimerCountdown timer ending at a fixed timestamp

Each block carries its own configuration object (selected by type), optional styleProperties, and an optional stylePresetID referencing a shared preset (see Style presets below).

Block configuration

The block object holds one configuration object matching its type. The field-level configuration for each type is below.

text — the text field is an HTML string, e.g. "<p>Subscribe to our newsletter</p>".

image (image object)

FieldDescription
idID of an existing image in the Images API
linkURL opened when the image is clicked
altTextAlternative text (max 200)
width / heightOriginal image dimensions in pixels
resizeWidthRendered width in pixels (max 2000)

button (button object)

FieldDescription
typeBehavior on click: link, submit, close, nextStep (link requires link)
textButton label (max 200)
linkURL opened when type is link
isFullWidthWhether the button spans the full width

lineSpace (lineSpace object)

FieldDescription
typeline (divider) or space (blank spacer)
widthDivider width percentage 1–100 (line only)
heightLine thickness 1–60px, or space height 12–240px

Input fieldsemailField, phoneNumberField, inputField, dateField, dropdownField, radioField, checkboxField. They share these common fields:

FieldDescription
labelField label (max 300)
placeholderPlaceholder text (max 250; not on date/radio/checkbox)
isRequiredWhether the field must be filled
requiredMessageMessage shown when a required field is empty
errorMessageMessage shown for invalid input (email, phone, date)

Type-specific fields:

TypeAdditional fields
emailField(common fields only)
phoneNumberFielddefaultCountryCode (ISO 3166-1 alpha-2, e.g. US)
inputFieldprofileField (firstName, lastName, address, city, state, zipCode, custom), customProfileField when custom
dateFieldprofileField (birthdate, custom), customProfileField, format (YYYY/MM/DD, MM/DD/YYYY, DD/MM/YYYY)
dropdownFieldprofileField (country, gender, custom), customProfileField, options[] (value/label, up to 100)
radioFieldprofileField (gender, custom), customProfileField, options[]
checkboxFieldprofileField (custom), customProfileField, options[]

legal (legal object)

FieldDescription
typeConsent type: gdpr or tcpa
labelConsent label shown next to the checkbox
descriptionConsent description text
linkURL to the privacy policy
requiredMessageMessage shown when consent is required but not given

discount (discount object)

FieldDescription
typeSource: static (fixed code) or wheelOfFortune (awarded by the wheel)
codeStatic discount code (required when type is static)

countdownTimer (countdownTimer object)

FieldDescription
endsAtCountdown end timestamp (RFC 3339, e.g. 2026-02-20T14:00:00Z)

wheelOfFortune (wheelOfFortune object)

FieldDescription
slices3–20 wheel slices (see below)
pointerColorWheel pointer color (hex)
widthWheel width percentage 30–100

Each slice:

FieldDescription
textSlice label (max 250)
discountCodeDiscount code awarded for the slice
probabilityWin probability percentage 0–100
isLosingWhether the slice is a losing slice
backgroundColor / textColorSlice colors (hex or transparent)
imageUrl / altTextOptional slice image and its alt text

General settings

content.generalSettings controls the presentation shared across the whole form.

FieldDescription
contentForm container width (300px–1000px) and overlay color shown behind the form
bodyForm body background color, border radius, width, style, and color
linkLink color used in text blocks
buttonPresetsReusable button styles referenced by blocks via stylePresetID (required — see Style presets below)
textPresetsReusable text styles referenced by blocks via stylePresetID (required — see Style presets below)
fieldStylesStyling shared across input fields: label, placeholder, and field appearance
closeButtonClose button color, background, and visibility
backgroundImageOptional background image (references an image in the Images API) with position, fit, padding, and size
positionWhere the form appears on the page (e.g. middleCenter, bottomLeft)

Style presets

Forms use button presets and text presets so blocks share consistent styling. A block applies a preset by setting its stylePresetID to the preset id.

generalSettings.buttonPresets must include these three presets:

primary_buttonsecondary_buttontertiary_button

generalSettings.textPresets must include these five presets:

heading_largeheading_mediumheading_smallparagraphfootnote

Additional form settings

Beyond content and targeting, a form accepts these optional top-level settings:

FieldDescription
doubleOptInDouble opt-in flow: confirmation email content plus a confirmation page or redirect
socialMediaSharingSocial preview metadata (title, description, image) for shared landing pages
autoRedirectRedirect applied after submission
contactTagsTags applied to contacts who submit the form (up to 100)
clickOutsideWhether clicking outside the form closes it
recaptchareCAPTCHA spam protection toggle

Each content also supports optional post-submission screens — successSections, subscribedSections, and unavailablePageSections — and a teaser shown before or after the form.

Targeting

targeting controls when and to whom a form is shown. All targeting rules are optional; omit the object entirely to show the form everywhere its display type allows.

RuleDescription
urlShow or hide the form on matching page URLs (exact or contains matches)
displayDisplay triggers: viewed page count, seconds on page, scroll depth, exit intent
frequencyHow often the form reappears (second, minute, hour, or day units)
deviceLimit to mobile or desktop
schedulingActive window (startsAt/endsAt, RFC 3339)
isBackInStockLimit to back-in-stock visitors
audienceTarget subscribers or notSubscribers
segmentsInclude/exclude by segment membership (segment IDs)
locationInclude/exclude by country, with optional state filtering
utmMatch UTM parameters (id, source, medium, campaign, term, content)
sourceMatch traffic source (googleAds, organic, direct, facebook, instagram, omnisendCommunication)

Constraints and pagination

ConstraintValue
Form name1–256 characters
Container width300px–1000px
Steps per form1–2
Columns per rowUp to 4
Font size8px–96px (4px minimum for legal blocks)
IDs (path parameters)24-character hexadecimal
List page size (limit)1–250 (default 100)
Forms sort fieldscreatedAt (default), updatedAt, name
Sort directionasc, desc (default)

List endpoints use cursor-based pagination: pass the after cursor from a response to fetch the next page, or before for the previous page (after and before cannot be combined). Sort parameters are only needed on the first request — subsequent cursor requests reuse the sort settings embedded in the cursor. See Pagination for details.

Scopes

ScopeGrants
forms.readList and get forms, templates, and A/B setups
forms.writeCreate, update, delete, enable, disable, and render forms; render templates; manage A/B setups

Example: Create a form

POST /api/forms creates a new form with the provided content, styling, and targeting. The form starts in draft status.

curl --request POST \
     --url https://api.omnisend.com/api/forms \
     --header 'Authorization: Omnisend-API-Key YOUR_API_KEY' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'Omnisend-Version: 2026-preview' \
     --data '{
  "name": "Newsletter Signup",
  "displayType": "popup",
  "content": {
    "generalSettings": {
      "content": { "width": "600px", "color": "#000000" },
      "body": {
        "backgroundColor": "#ffffff",
        "borderRadius": "8px",
        "borderWidth": "1px",
        "borderStyle": "solid",
        "borderColor": "#cccccc"
      },
      "link": { "color": "#0000ee" },
      "buttonPresets": [
        {
          "id": "primary_button",
          "name": "Primary",
          "styles": {
            "backgroundColor": "#000000",
            "borderRadius": "8px",
            "borderWidth": "1px",
            "borderStyle": "solid",
            "borderColor": "#000000",
            "fontWeight": "bold",
            "fontStyle": "normal",
            "textDecoration": "none",
            "fontFamily": "Arial",
            "fontSize": "16px",
            "color": "#ffffff"
          }
        },
        {
          "id": "secondary_button",
          "name": "Secondary",
          "styles": {
            "backgroundColor": "#ffffff",
            "borderRadius": "8px",
            "borderWidth": "1px",
            "borderStyle": "solid",
            "borderColor": "#000000",
            "fontWeight": "normal",
            "fontStyle": "normal",
            "textDecoration": "none",
            "fontFamily": "Arial",
            "fontSize": "16px",
            "color": "#000000"
          }
        },
        {
          "id": "tertiary_button",
          "name": "Tertiary",
          "styles": {
            "backgroundColor": "transparent",
            "borderRadius": "0px",
            "borderWidth": "0px",
            "borderStyle": "solid",
            "borderColor": "transparent",
            "fontWeight": "normal",
            "fontStyle": "normal",
            "textDecoration": "underline",
            "fontFamily": "Arial",
            "fontSize": "16px",
            "color": "#000000"
          }
        }
      ],
      "textPresets": [
        { "id": "heading_large", "name": "Heading Large", "styles": { "fontFamily": "Arial", "fontSize": "32px", "color": "#000000", "lineHeight": "125%" } },
        { "id": "heading_medium", "name": "Heading Medium", "styles": { "fontFamily": "Arial", "fontSize": "24px", "color": "#000000", "lineHeight": "125%" } },
        { "id": "heading_small", "name": "Heading Small", "styles": { "fontFamily": "Arial", "fontSize": "20px", "color": "#000000", "lineHeight": "125%" } },
        { "id": "paragraph", "name": "Paragraph", "styles": { "fontFamily": "Arial", "fontSize": "16px", "color": "#000000", "lineHeight": "150%" } },
        { "id": "footnote", "name": "Footnote", "styles": { "fontFamily": "Arial", "fontSize": "12px", "color": "#757575", "lineHeight": "150%" } }
      ],
      "fieldStyles": {
        "fontFamily": "Arial",
        "fontSize": "14px",
        "errorColor": "#ff0000",
        "label": { "color": "#000000" },
        "placeholder": { "color": "#999999" },
        "field": {
          "color": "#000000",
          "backgroundColor": "#ffffff",
          "borderRadius": "4px",
          "borderStyle": "solid",
          "borderColor": "#cccccc",
          "borderWidth": "1px"
        }
      }
    },
    "steps": [
      {
        "sections": [
          {
            "rows": [
              {
                "columns": [
                  {
                    "width": "100%",
                    "blocks": [
                      { "type": "text", "role": "title", "text": "<p>Subscribe to our newsletter</p>", "stylePresetID": "heading_large" },
                      {
                        "type": "emailField",
                        "emailField": {
                          "placeholder": "[email protected]",
                          "isRequired": true,
                          "requiredMessage": "Email is required",
                          "errorMessage": "Enter a valid email address",
                          "label": "Email"
                        }
                      },
                      { "type": "button", "button": { "type": "submit", "text": "Subscribe", "link": "", "isFullWidth": true } }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  },
  "targeting": { "display": { "afterSeconds": 5 }, "device": "desktop" }
}'

Example: Enable a form

POST /api/forms/{formID}/enable publishes the form and starts serving it to visitors according to its targeting rules. The call is idempotent.

curl --request POST \
     --url https://api.omnisend.com/api/forms/000000000000000000000001/enable \
     --header 'Authorization: Omnisend-API-Key YOUR_API_KEY' \
     --header 'Omnisend-Version: 2026-preview' \
     --header 'accept: application/json'