---
title: "Publish a form"
method: POST
path: "/forms/{formId}/publish"
tags: ["Forms"]
---

# Publish a form

`POST /forms/{formId}/publish`

## Request

- Base URL: `https://api.foxform.app`
- URL: `https://api.foxform.app/forms/{formId}/publish`
- Auth: API key in header `x-api-key`

Generates the static HTML, uploads it to S3 and invalidates the CDN. Returns 402 PAID_FIELDS_REQUIRED when a free-plan user has Pro-only fields (file upload, picture choice, video upload, testimonial photo).

## Path parameters

- `formId` string, required

## Response `200`

Published.

- PublishFormResponse
  - `success` boolean
  - `data` Form
    - `id` string
    - `user_id` string
    - `title` string
    - `description` string, nullable
    - `slug` string
    - `status` 'draft' | 'published' | 'closed'
    - `theme` 'amber' | 'base' | 'midnight' | 'ocean' | 'sunset' | 'forest' | 'lavender' | 'minimal': Form theme. New forms default to amber (copper-to-amber gradient, the FoxForm default); base is the neutral graphite option.
    - `questions` QuestionConfig[]
      - `id` string, required
      - `type` 'welcome' | 'loading' | 'result' | 'end' | 'short_text' | 'long_text' | 'dropdown' | 'checkboxes' | 'multiple_choice' | 'email' | 'phone' | 'number' | 'date' | 'rating' | 'opinion_scale' | 'nps' | 'yes_no' | 'file_upload' | 'picture_choice' | 'url' | 'slider' | 'alert' | 'testimonials' | 'media' | 'timer' | 'arguments' | 'price' | 'progress_bar', required
      - `title` string, required
      - `description` string
      - `required` boolean, required
      - `buttonText` string
      - `options` string[]: Legacy plain options (dropdown/checkboxes/multiple_choice). Migrated into `choices`.
      - `choices` QuestionOption[]: Canonical option objects (funnel: points/value).
        - `id` string, required
        - `label` string, required
        - `icon` string
        - `imageUrl` string
        - `points` number: Adds to {{score}} when selected.
        - `value` string: Exposed via {{variable}} for later steps.
      - `minValue` number
      - `maxValue` number
      - `placeholder` string
      - `allowedFileTypes` string[]
      - `maxFileSize` number: MB
      - `maxFiles` integer
      - `allowMultipleFiles` boolean
      - `defaultCountry` string: ISO 2-letter (phone).
      - `randomize` boolean
      - `alphabetical` boolean
      - `allowOther` boolean
      - `otherLabel` string
      - `otherPlaceholder` string
      - `style` QuestionStyle
        - `theme` string
        - `fontFamily` string
        - `textColor` string
        - `accentColor` string
        - `buttonBackgroundColor` string
        - `buttonTextColor` string
        - `verticalAlignment` 'center' | 'left' | 'right'
        - `backgroundType` 'theme' | 'image' | 'color'
        - `backgroundImage` string
        - `backgroundColor` string
      - `logic` QuestionLogic
        - `autoAdvance` object
          - `enabled` boolean
          - `delaySeconds` number
        - `navigationBehavior` object
          - `onButtonClick` 'next_screen' | 'previous_screen' | 'specific_screen' | 'end_form'
          - `onAutoAdvance` 'next_screen' | 'previous_screen' | 'specific_screen' | 'end_form'
          - `targetScreenId` string
        - `conditionalNavigationV2` ConditionalLogicV2
          - `enabled` boolean
          - `groups` ConditionGroup[]
            - `id` string
            - `conditions` ConditionV2[]
              - …
            - `then` object
              - …
        - `display` DisplayRule
          - `enabled` boolean
          - `groups` ConditionGroup[]
            - `id` string
            - `conditions` ConditionV2[]
              - …
            - `then` object
              - …
          - `showAfterSeconds` number
      - `shape` string: Rating icon shape (star, heart, smiley, thumbs_up, crown, ...).
      - `showNumbers` boolean
      - `label0` string
      - `label5` string
      - `label10` string
      - `colorScheme` 'gradient' | 'monochrome': NPS.
      - `npsLeftLabel` string
      - `npsRightLabel` string
      - `step` number
      - `initialValue` number
      - `prefix` string
      - `suffix` string
      - `showCurrentValue` boolean
      - `dateFormat` 'MDY' | 'DMY' | 'YMD'
      - `dateSeparator` '/' | '-' | '.'
      - `itemsPerRow` 2 | 3
      - `aspectRatio` '1:1' | '4:3' | '3:4' | '16:9'
      - `images` object[]
        - `id` string
        - `url` string
        - `label` string
        - `points` number
        - `value` string
      - `multipleSelection` boolean
      - `showLabels` boolean
      - `numberModel` 'plain' | 'currency' | 'percentage' | 'decimal' | 'height' | 'weight'
      - `currency` 'BRL' | 'USD' | 'EUR'
      - `decimals` integer
      - `heightUnit` 'cm' | 'in'
      - `weightUnit` 'kg' | 'lb'
      - `videoSource` 'upload' | 'url' | 'embed'
      - `videoUrl` string
      - `videoEmbed` string
      - `videoAspectRatio` '16:9' | '1:1' | '4:5' | 'original'
      - `videoObjectFit` 'cover' | 'contain'
      - `caption` string
      - `autoplay` boolean
      - `loop` boolean
      - `requirePlayback` boolean
      - `countdownType` 'until_date' | 'fixed_period'
      - `periodDays` integer
      - `periodHours` integer
      - `periodMinutes` integer
      - `periodSeconds` integer
      - `targetDate` string
      - `onZero` 'show_message' | 'hide' | 'redirect' | 'auto_advance' | 'submit_form'
      - `redirectUrl` string
      - `expireMessage` string
      - `resultCards` ResultCard[]
        - `id` string
        - `iconUrl` string
        - `imageUrl` string
        - `title` string
        - `description` string
        - `buttonText` string
        - `buttonAction` ButtonAction
          - `type` 'next_screen' | 'previous_screen' | 'specific_screen' | 'end_form'
          - `targetScreenId` string
          - `url` string
          - `openNewTab` boolean
        - `display` DisplayRule
          - `enabled` boolean
          - `groups` ConditionGroup[]
            - `id` string
            - `conditions` ConditionV2[]
              - …
            - `then` object
              - …
          - `showAfterSeconds` number
      - `alerts` AlertItem[]
        - `id` string
        - `title` string
        - `message` string
        - `color` string: theme|error|info|success|warning or hex.
        - `severity` 'warning' | 'info' | 'success' | 'error' | 'custom'
        - `iconKey` string
        - `highlight` boolean
        - `display` DisplayRule
          - `enabled` boolean
          - `groups` ConditionGroup[]
            - `id` string
            - `conditions` ConditionV2[]
              - …
            - `then` object
              - …
          - `showAfterSeconds` number
      - `argumentItems` ArgumentItem[]
        - `id` string
        - `imageUrl` string
        - `title` string
        - `text` string
        - `display` DisplayRule
          - `enabled` boolean
          - `groups` ConditionGroup[]
            - `id` string
            - `conditions` ConditionV2[]
              - …
            - `then` object
              - …
          - `showAfterSeconds` number
      - `testimonialItems` TestimonialItem[]
        - `id` string
        - `photoUrl` string: Photo makes the field Pro-only.
        - `name` string
        - `handle` string
        - `stars` integer
        - `text` string
        - `display` DisplayRule
          - `enabled` boolean
          - `groups` ConditionGroup[]
            - `id` string
            - `conditions` ConditionV2[]
              - …
            - `then` object
              - …
          - `showAfterSeconds` number
      - `testimonialsLayout` 'carousel' | 'single' | 'grid'
      - `showRatings` boolean
      - `autoRotate` boolean
      - `layout` 'grid' | 'list'
      - `progressLabel` string
      - `progressValueType` 'fixed' | 'variable'
      - `progressValue` number
      - `progressExpression` string
      - `showPercentage` boolean
      - `priceModel` 'single' | 'selection' | 'table'
      - `priceCards` PriceCard[]
        - `id` string
        - `highlightText` string
        - `title` string
        - `tag` string
        - `prefix` string
        - `value` string
        - `suffix` string
        - `description` string
        - `color` string
        - `priceType` 'illustrative' | 'redirect' | 'checkout'
        - `buttonText` string
        - `url` string
        - `openNewTab` boolean
        - `display` DisplayRule
          - `enabled` boolean
          - `groups` ConditionGroup[]
            - `id` string
            - `conditions` ConditionV2[]
              - …
            - `then` object
              - …
          - `showAfterSeconds` number
      - `priceRows` object[]
      - `variableName` string: Token used in {{...}} interpolation (defaults to id).
      - `files` object[]
        - `url` string
        - `name` string
        - `size` number
        - `mime` string
        - `gdriveFileId` string
      - `mediaUrl` string
      - `mediaType` 'image' | 'video' | 'iframe'
      - `buttonEnabled` boolean: End screen only. false hides the button, leaving just the title and description (all formats, including chatbot). Missing or true = button shown.
      - `buttonLink` string
      - `buttonOpenNewTab` boolean
      - `socialEnabled` boolean
      - `socialLinks` object[]
        - `platform` string
        - `url` string
        - `iconUrl` string
    - `thank_you_message` string
    - `webhook_url` string, nullable
    - `show_progress_bar` boolean
    - `show_navigation_arrows` boolean
    - `email_notifications` boolean
    - `hide_branding` boolean: Remove 'Powered by FoxForm' (Pro/Starter only).
    - `published_at` string, date-time
    - `created_at` string, date-time
    - `updated_at` string, date-time
  - `message` string
  - `code` string: PAID_FIELDS_REQUIRED on 402.
  - `paidFields` PaidField[]
    - `feature` 'file_upload' | 'picture_choice' | 'video_upload' | 'testimonials_photo'
    - `questionIds` string[]
  - `prohibitedFields` object[]
    - `questionId` string
    - `questionTitle` string
    - `reason` string
    - `category` string

## Other responses

- `402`: Paid fields require an upgrade.

---

[API](https://skmtc.dev/foxform/apis/foxform-api.md) · [All operations](https://skmtc.dev/foxform/apis/foxform-api/llms.txt) · [OpenAPI document](https://skmtc.dev/foxform/apis/foxform-api/revisions/fe83b1999541?raw)
