Skip to content

Forms

Create a form

POST/v1/forms

Create a draft form for a brand. When the workspace already has all the forms its plan includes, it answers 403 plan_limit. Drafts count toward that limit. See Paid checks.

Body

JSON, with Content-Type: application/json.

  • brandIdstringrequired

    The brand the form belongs to.

  • namestringrequired

    The form's name.

    1–200 chars

  • draftobject

    The whole form, in the same shape as in PATCH /v1/forms/{formId}. Leave it out to start with one empty step and one ending called "Thank you", which shows a message and counts as a lead.

    Show 3 fields
    • stepsarray of objectrequired

      min 1 item

      Show 7 fields
      • idstringrequired
      • blocksarray of one of 2required
        Show 2 options
        • Option 1

        • Option 2

      • rulesarray of objectrequired
        Show 2 fields
        • whenarray of objectrequired

          All must match (AND).

          min 1 item

          Show 3 fields
          • fieldIdstringrequired
          • openumrequired

            One of "equals", "not_equals", "in", "not_in", "includes", "gt", "lt", "answered"

          • valuestring or number or array of string
        • gotoone of 2required

          Where the visitor goes next: { kind: "step", stepId } shows that step; { kind: "ending", endingId } finishes the form at that ending (the response is submitted).

          Show 2 options
          • kind: "step"

            • kind"step"required
            • stepIdstringrequired
          • kind: "ending"

            • kind"ending"required
            • endingIdstringrequired
      • nextone of 2required

        The default way on: a step or ending, or { kind: "following" }: the next step in order, or after the last step the first ending.

        Show 2 options
        • Option 1

          Where the visitor goes next: { kind: "step", stepId } shows that step; { kind: "ending", endingId } finishes the form at that ending (the response is submitted).

        • kind: "following"

          • kind"following"required
      • titlestring
      • descriptionstring
      • buttonLabelstring
    • endingsarray of objectrequired

      Every path stops at one of these. The first is where the last step goes by default.

      min 1 item

      Show 4 fields
      • idstringrequired

        Unique among endings (its own namespace).

      • namestringrequired

        The builder's name for it, e.g. "Qualified" or "Not a fit". Reported in responses, webhooks and page events.

        min 1 char

      • actionone of 3required
        Show 3 options
        • kind: "message"

          Show a thank-you message (body is Markdown).

          • kind"message"required
          • titlestringrequired
          • bodystringrequired
        • kind: "redirect"

          Send the visitor to a URL (no thank-you screen).

          • kind"redirect"required
          • urlstringrequired
          • appendContactbooleanrequired

            Add first_name, last_name, email and phone to the URL.

        • kind: "handoff"

          Hand back to the site: the form closes and the page gets the forms:submit event, nothing else.

          • kind"handoff"required
      • countsAsLeadbooleanrequired

        Reaching this ending reports a Lead to ad tracking (Meta Pixel + CAPI Lead, GA4 generate_lead). Turn off for disqualifying endings.

    • settingsobjectrequired
      Show 7 fields
      • progressBarbooleanrequired
      • partialCapturebooleanrequired

        Save unfinished responses: keeps what visitors entered even if they don't finish, once there's a valid email, phone or Telegram username (stored with status partial). Webhook events: submission.abandoned (left without finishing after giving a valid email, phone or Telegram username: page closed, or 5 minutes with no activity; once per response), submission.completed. Needs the plan feature partialCapture (workspaces.entitlements features): turning it on without it is 403 plan_feature, and a new form on such a plan starts with it false. If the plan later loses the feature, the live form stops saving unfinished responses at once (no resume, no submission.abandoned) and this stays true, applying again after an upgrade.

      • turnstilebooleanrequired
      • submitLabelstringrequired

        min 1 char

      • returningVisitorenum

        With partialCapture on: what happens when someone with an unfinished response comes back later and finishes. "update" (default): in the same browser (a resume token the server issued with the first save, kept in localStorage on the host site; valid 30 days after the last activity, Safari may clear it after 7 days without a visit), their earlier response is completed (same submission id). "new": the earlier response stays as it was and a new one is saved. The same email or phone never continues or changes a response, since anyone can type it: in another browser it saves a new response whose earlierSubmissionId links to that unfinished one. A completed response is never changed.

        One of "update", "new"

      • displayobject
        Show 4 fields
        • viewenumrequired

          How the form opens: "popup" or "fullscreen" for a button or inline field; "widget" is the corner card and goes with onPage "widget". Ignored by onPage "embed", which opens nothing (any value is accepted; a data-forms-open button or Forms.open for the same form still opens in this view).

          One of "popup", "widget", "fullscreen"

        • sideenumrequired

          The corner the widget docks to. Ignored by the other views.

          One of "right", "left"

        • onPageenum

          What starts the form on the site. "button": the site's own buttons or links with data-forms-open. "inline" (Field and Button): the first question on the page with a button beside it (an element with data-forms-inline). "embed" (Full form): the whole form in the page, inside an element with data-forms-embed, at that element's width; every step, the progress bar, Back, a texted-code step and the ending stay in that element, and nothing opens over the page (so view and buttonLabel don't apply; the form uses its own Continue and submit labels). "widget" (Corner widget): a floating button in a bottom corner, shown as the page loads (an element with data-forms-widget on the page), that opens the form in a card in that corner. Left out: "widget" when view is "widget", else "button".

          One of "button", "inline", "embed", "widget"

        • buttonLabelstring

          The button's text: the corner widget's floating button and the inline field's button ("Get started" when left out or blank). A site's own data-forms-open button keeps its own text; data-forms-button on an inline element overrides this. Ignored by onPage "embed".

          max 40 chars

      • hideBadgeboolean

        true: the live form leaves out the "Powered by ayeform" badge under it (default false: shown). Needs the plan feature hideBadge (workspaces.entitlements features): turning it on without it is 403 plan_feature. If the plan later loses the feature, the live form shows the badge again at once and this stays true, applying again after an upgrade. Like every setting, it goes live on publish.

Response

  • idstringrequired

    The form's id.

  • brandIdstringrequired

    The brand the form belongs to.

  • workspaceIdstringrequired

    The workspace the form belongs to.

  • namestringrequired

    The form's name.

  • statusenumrequired

    draft until it's first published, then published while it's live. unpublished once it's taken offline; its versions are kept.

    One of "draft", "published", "unpublished"

  • publishedVersionnumber or nullrequired

    The number of the live version. Null if the form was never published.

  • publishedAtnumber or nullrequired

    When the latest version was published, in milliseconds since the epoch. Null if never.

  • hasUnpublishedChangesbooleanrequired

    Whether the draft or theme overrides changed since the form was last published.

  • changedAtnumber or nullrequired

    When the draft or theme overrides last changed, in milliseconds since the epoch. Null if they were never edited.

  • partialCapturebooleanrequired

    Whether the draft has "Save unfinished responses" on. The webhook event for people who left (submission.abandoned) needs it, and the plan feature partialCapture too.

  • stepCountintegerrequired

    How many steps the draft has.

    -9007199254740991–9007199254740991

  • blockCountintegerrequired

    How many questions and other blocks the draft has, across all steps.

    -9007199254740991–9007199254740991

  • createdAtnumberrequired

    When the form was created, in milliseconds since the epoch.

  • updatedAtnumberrequired

    When anything about the form last changed, in milliseconds since the epoch.

  • draftobjectrequired

    The whole form as it is now, unpublished edits included. It holds steps in order, then endings, and settings, in the same shape as draft in PATCH /v1/forms/{formId}.

  • themeOverridesobjectrequired

    Theme values that override the brand theme for this form.

    Show 13 fields
    • accentstring
    • accentTextstring
    • backgroundstring
    • surfacestring
    • textstring
    • mutedstring
    • borderstring
    • radiusnumber

      0–48

    • buttonRadiusnumber

      0–48

    • fontstring
    • headingFontstring

      max 500 chars

    • backdropstring
    • fontStylesheetstring

      max 2000 chars · uri

  • trackingOverridesobjectrequired

    Whether this form fires the brand's Meta and GA4 tracking, and its own Jornaya campaign key.

    Show 3 fields
    • metabooleanrequired

      Whether this form fires the brand's Meta Lead, in the browser and through the Conversions API.

    • ga4booleanrequired

      Whether this form fires the brand's GA4 generate_lead event.

    • jornayaCampaignKeystring

      This form's own Jornaya campaign key. Leave it out to use the brand's. It applies while the brand has Jornaya on. A page loads one campaign script, so with two forms on a page the first one's key is used.

  • picturesarray of objectrequired

    Pictures AI is making in the background for image choice options after an AI build or fix. If a picture can't be made, or its option was removed or got a picture in the meantime, it drops off this list and the option stays as it is. You can add a picture yourself with POST /v1/forms/{formId}/images. Publishing while a picture is still making fails like a missing picture would, with a message that it's still coming.

    Show 4 fields
    • blockIdstringrequired

      The id of the image choice question.

    • valuestringrequired

      The value of the option the picture is for.

    • statusenumrequired

      making while AI makes the picture. added once it's on the option as imageId in the draft.

      One of "making", "added"

    • imageIdstring or nullrequired

      The picture's id once it's added. Null while it's being made.

Errors answer with a status and the error shape.