FoxForm Forms API

Create, read, update, delete, clone, publish and AI-generate forms/funnels.

GitHub OpenAPI

Operations 9

GET /forms List the user's forms #
POST /forms Create a form #
GET /forms/{formId} Get a form by ID #
PUT /forms/{formId} Update a form #
DELETE /forms/{formId} Delete a form #
GET /forms/slug/{slug} Get a published form by public slug #
POST /forms/{formId}/clone Duplicate a form #
POST /forms/{formId}/publish Publish a form #
POST /forms/{formId}/unpublish Unpublish a form #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/foxform-app:foxform-app-forms-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

foxform-app-forms-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: FoxForm Forms API
  version: 1.0.0
  description: Public REST API for FoxForm — manage forms, read responses and analytics. Authenticate with a FoxForm API key (see the "MCP & API" area in the dashboard). Account/billing/onboarding endpoints are internal and not part of the public API.
  contact:
    name: FoxForm
    url: https://foxform.app
  license:
    name: Proprietary
servers:
- url: https://api.foxform.app
  description: Production
- url: https://api-staging.foxform.app
  description: Staging
security:
- ApiKey: []
tags:
- name: Forms
  description: Create, read, update, delete, clone, publish and AI-generate forms/funnels.
paths:
  /forms:
    get:
      tags:
      - Forms
      summary: List the user's forms
      parameters:
      - name: page
        in: query
        schema:
          type: integer
          default: 1
      - name: limit
        in: query
        schema:
          type: integer
          default: 20
      responses:
        '200':
          description: Paginated forms.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListFormsResponse'
      security:
      - ApiKey: []
      operationId: getForms
      x-operation-id-source: derived
    post:
      tags:
      - Forms
      summary: Create a form
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FormInput'
      responses:
        '200':
          description: Created form.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetFormResponse'
      security:
      - ApiKey: []
      operationId: postForms
      x-operation-id-source: derived
  /forms/{formId}:
    parameters:
    - name: formId
      in: path
      required: true
      schema:
        type: string
    get:
      tags:
      - Forms
      summary: Get a form by ID
      responses:
        '200':
          description: Form.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetFormResponse'
        '404':
          $ref: '#/components/responses/Error'
      security:
      - ApiKey: []
      operationId: getFormsByFormId
      x-operation-id-source: derived
    put:
      tags:
      - Forms
      summary: Update a form
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FormInput'
      responses:
        '200':
          description: Updated form.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetFormResponse'
      security:
      - ApiKey: []
      operationId: putFormsByFormId
      x-operation-id-source: derived
    delete:
      tags:
      - Forms
      summary: Delete a form
      responses:
        '200':
          $ref: '#/components/responses/Success'
      security:
      - ApiKey: []
      operationId: deleteFormsByFormId
      x-operation-id-source: derived
  /forms/slug/{slug}:
    get:
      tags:
      - Forms
      summary: Get a published form by public slug
      description: Public, unauthenticated. Used to render the form player.
      security: []
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Form.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetFormResponse'
        '404':
          $ref: '#/components/responses/Error'
      operationId: getFormsSlugBySlug
      x-operation-id-source: derived
  /forms/{formId}/clone:
    post:
      tags:
      - Forms
      summary: Duplicate a form
      parameters:
      - name: formId
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Cloned form.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetFormResponse'
      security:
      - ApiKey: []
      operationId: postFormsByFormIdClone
      x-operation-id-source: derived
  /forms/{formId}/publish:
    post:
      tags:
      - Forms
      summary: Publish a form
      description: 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).
      parameters:
      - name: formId
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Published.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublishFormResponse'
        '402':
          description: Paid fields require an upgrade.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublishFormResponse'
      security:
      - ApiKey: []
      operationId: postFormsByFormIdPublish
      x-operation-id-source: derived
  /forms/{formId}/unpublish:
    post:
      tags:
      - Forms
      summary: Unpublish a form
      parameters:
      - name: formId
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          $ref: '#/components/responses/Success'
      security:
      - ApiKey: []
      operationId: postFormsByFormIdUnpublish
      x-operation-id-source: derived
components:
  schemas:
    PublishFormResponse:
      type: object
      properties:
        success:
          type: boolean
        data:
          allOf:
          - $ref: '#/components/schemas/Form'
          type: object
        message:
          type: string
        code:
          type: string
          description: PAID_FIELDS_REQUIRED on 402.
        paidFields:
          type: array
          items:
            $ref: '#/components/schemas/PaidField'
        prohibitedFields:
          type: array
          items:
            type: object
            properties:
              questionId:
                type: string
              questionTitle:
                type: string
              reason:
                type: string
              category:
                type: string
    ButtonAction:
      type: object
      properties:
        type:
          $ref: '#/components/schemas/NavigationTarget'
        targetScreenId:
          type: string
        url:
          type: string
        openNewTab:
          type: boolean
    SuccessResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        message:
          type: string
    NavigationTarget:
      type: string
      enum:
      - next_screen
      - previous_screen
      - specific_screen
      - end_form
    QuestionType:
      type: string
      enum:
      - 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
    QuestionStyle:
      type: object
      properties:
        theme:
          type: string
        fontFamily:
          type: string
        textColor:
          type: string
        accentColor:
          type: string
        buttonBackgroundColor:
          type: string
        buttonTextColor:
          type: string
        verticalAlignment:
          type: string
          enum:
          - center
          - left
          - right
        backgroundType:
          type: string
          enum:
          - theme
          - image
          - color
        backgroundImage:
          type: string
        backgroundColor:
          type: string
    ResultCard:
      type: object
      properties:
        id:
          type: string
        iconUrl:
          type: string
        imageUrl:
          type: string
        title:
          type: string
        description:
          type: string
        buttonText:
          type: string
        buttonAction:
          $ref: '#/components/schemas/ButtonAction'
        display:
          $ref: '#/components/schemas/DisplayRule'
    TestimonialItem:
      type: object
      properties:
        id:
          type: string
        photoUrl:
          type: string
          description: Photo makes the field Pro-only.
        name:
          type: string
        handle:
          type: string
        stars:
          type: integer
          minimum: 1
          maximum: 5
        text:
          type: string
        display:
          $ref: '#/components/schemas/DisplayRule'
    QuestionLogic:
      type: object
      properties:
        autoAdvance:
          type: object
          properties:
            enabled:
              type: boolean
            delaySeconds:
              type: number
        navigationBehavior:
          type: object
          properties:
            onButtonClick:
              $ref: '#/components/schemas/NavigationTarget'
            onAutoAdvance:
              $ref: '#/components/schemas/NavigationTarget'
            targetScreenId:
              type: string
        conditionalNavigationV2:
          $ref: '#/components/schemas/ConditionalLogicV2'
        display:
          $ref: '#/components/schemas/DisplayRule'
    ArgumentItem:
      type: object
      properties:
        id:
          type: string
        imageUrl:
          type: string
        title:
          type: string
        text:
          type: string
        display:
          $ref: '#/components/schemas/DisplayRule'
    QuestionConfig:
      type: object
      required:
      - id
      - type
      - title
      - required
      description: A single screen/field. Covers input, selection, scale, flow (welcome/loading/result/end) and content (alert/testimonials/video/timer/arguments/price/progress_bar) types, plus the funnel layer (points, values, {{variables}}, calc, conditional navigation/display, rich text).
      properties:
        id:
          type: string
        type:
          $ref: '#/components/schemas/QuestionType'
        title:
          type: string
        description:
          type: string
        required:
          type: boolean
        buttonText:
          type: string
        options:
          type: array
          items:
            type: string
          description: Legacy plain options (dropdown/checkboxes/multiple_choice). Migrated into `choices`.
        choices:
          type: array
          items:
            $ref: '#/components/schemas/QuestionOption'
          description: 'Canonical option objects (funnel: points/value).'
        minValue:
          type: number
        maxValue:
          type: number
        placeholder:
          type: string
        allowedFileTypes:
          type: array
          items:
            type: string
        maxFileSize:
          type: number
          description: MB
        maxFiles:
          type: integer
        allowMultipleFiles:
          type: boolean
        defaultCountry:
          type: string
          description: ISO 2-letter (phone).
        randomize:
          type: boolean
        alphabetical:
          type: boolean
        allowOther:
          type: boolean
        otherLabel:
          type: string
        otherPlaceholder:
          type: string
        style:
          $ref: '#/components/schemas/QuestionStyle'
        logic:
          $ref: '#/components/schemas/QuestionLogic'
        shape:
          type: string
          description: Rating icon shape (star, heart, smiley, thumbs_up, crown, ...).
        showNumbers:
          type: boolean
        label0:
          type: string
        label5:
          type: string
        label10:
          type: string
        colorScheme:
          type: string
          enum:
          - gradient
          - monochrome
          description: NPS.
        npsLeftLabel:
          type: string
        npsRightLabel:
          type: string
        step:
          type: number
        initialValue:
          type: number
        prefix:
          type: string
        suffix:
          type: string
        showCurrentValue:
          type: boolean
        dateFormat:
          type: string
          enum:
          - MDY
          - DMY
          - YMD
        dateSeparator:
          type: string
          enum:
          - /
          - '-'
          - .
        itemsPerRow:
          type: integer
          enum:
          - 2
          - 3
        aspectRatio:
          type: string
          enum:
          - '1:1'
          - '4:3'
          - '3:4'
          - '16:9'
        images:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
              url:
                type: string
              label:
                type: string
              points:
                type: number
              value:
                type: string
        multipleSelection:
          type: boolean
        showLabels:
          type: boolean
        numberModel:
          type: string
          enum:
          - plain
          - currency
          - percentage
          - decimal
          - height
          - weight
        currency:
          type: string
          enum:
          - BRL
          - USD
          - EUR
        decimals:
          type: integer
        heightUnit:
          type: string
          enum:
          - cm
          - in
        weightUnit:
          type: string
          enum:
          - kg
          - lb
        videoSource:
          type: string
          enum:
          - upload
          - url
          - embed
        videoUrl:
          type: string
        videoEmbed:
          type: string
        videoAspectRatio:
          type: string
          enum:
          - '16:9'
          - '1:1'
          - '4:5'
          - original
        videoObjectFit:
          type: string
          enum:
          - cover
          - contain
        caption:
          type: string
        autoplay:
          type: boolean
        loop:
          type: boolean
        requirePlayback:
          type: boolean
        countdownType:
          type: string
          enum:
          - until_date
          - fixed_period
        periodDays:
          type: integer
        periodHours:
          type: integer
        periodMinutes:
          type: integer
        periodSeconds:
          type: integer
        targetDate:
          type: string
        onZero:
          type: string
          enum:
          - show_message
          - hide
          - redirect
          - auto_advance
          - submit_form
        redirectUrl:
          type: string
        expireMessage:
          type: string
        resultCards:
          type: array
          items:
            $ref: '#/components/schemas/ResultCard'
        alerts:
          type: array
          items:
            $ref: '#/components/schemas/AlertItem'
        argumentItems:
          type: array
          items:
            $ref: '#/components/schemas/ArgumentItem'
        testimonialItems:
          type: array
          items:
            $ref: '#/components/schemas/TestimonialItem'
        testimonialsLayout:
          type: string
          enum:
          - carousel
          - single
          - grid
        showRatings:
          type: boolean
        autoRotate:
          type: boolean
        layout:
          type: string
          enum:
          - grid
          - list
        progressLabel:
          type: string
        progressValueType:
          type: string
          enum:
          - fixed
          - variable
        progressValue:
          type: number
        progressExpression:
          type: string
        showPercentage:
          type: boolean
        priceModel:
          type: string
          enum:
          - single
          - selection
          - table
        priceCards:
          type: array
          items:
            $ref: '#/components/schemas/PriceCard'
        priceRows:
          type: array
          items:
            type: object
        variableName:
          type: string
          description: Token used in {{...}} interpolation (defaults to id).
        files:
          type: array
          items:
            type: object
            properties:
              url:
                type: string
              name:
                type: string
              size:
                type: number
              mime:
                type: string
              gdriveFileId:
                type: string
        mediaUrl:
          type: string
        mediaType:
          type: string
          enum:
          - image
          - video
          - iframe
        buttonEnabled:
          type: boolean
          description: End screen only. false hides the button, leaving just the title and description (all formats, including chatbot). Missing or true = button shown.
        buttonLink:
          type: string
        buttonOpenNewTab:
          type: boolean
        autoRedirect:
          type: boolean
          description: End screen only. true sends respondents to autoRedirectUrl automatically after they submit (the response is recorded first). Shows a 'Redirecting in N s' countdown with a 'Go now' link. All formats.
        autoRedirectUrl:
          type: string
          format: uri
          description: End screen only. Absolute http/https URL. Query params from the form link (utm_*, gclid, ...) are appended and {{param}} tokens are filled from them, like buttonLink.
        autoRedirectDelay:
          type: integer
          minimum: 0
          maximum: 10
          default: 3
          description: End screen only. Seconds to wait before redirecting.
        socialEnabled:
          type: boolean
        socialLinks:
          type: array
          items:
            type: object
            properties:
              platform:
                type: string
              url:
                type: string
              iconUrl:
                type: string
    GetFormResponse:
      type: object
      properties:
        success:
          type: boolean
        data:
          $ref: '#/components/schemas/Form'
    Form:
      type: object
      properties:
        id:
          type: string
        user_id:
          type: string
        title:
          type: string
        description:
          type:
          - string
          - 'null'
        slug:
          type: string
        status:
          type: string
          enum:
          - draft
          - published
          - closed
        theme:
          type: string
          description: Form theme. New forms default to amber (copper-to-amber gradient, the FoxForm default); base is the neutral graphite option.
          default: amber
          enum:
          - amber
          - base
          - midnight
          - ocean
          - sunset
          - forest
          - lavender
          - minimal
        questions:
          type: array
          items:
            $ref: '#/components/schemas/QuestionConfig'
        thank_you_message:
          type: string
        webhook_url:
          type:
          - string
          - 'null'
        show_progress_bar:
          type: boolean
        show_navigation_arrows:
          type: boolean
        email_notifications:
          type: boolean
        hide_branding:
          type: boolean
          description: Remove 'Powered by FoxForm' (Pro/Starter only).
        published_at:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    ConditionalLogicV2:
      type: object
      properties:
        enabled:
          type: boolean
        groups:
          type: array
          items:
            $ref: '#/components/schemas/ConditionGroup'
    ConditionGroup:
      type: object
      description: Conditions AND-joined; groups OR-joined.
      properties:
        id:
          type: string
        conditions:
          type: array
          items:
            $ref: '#/components/schemas/ConditionV2'
        then:
          type: object
          properties:
            type:
              $ref: '#/components/schemas/NavigationTarget'
            targetScreenId:
              type: string
    PriceCard:
      type: object
      properties:
        id:
          type: string
        highlightText:
          type: string
        title:
          type: string
        tag:
          type: string
        prefix:
          type: string
        value:
          type: string
        suffix:
          type: string
        description:
          type: string
        color:
          type: string
        priceType:
          type: string
          enum:
          - illustrative
          - redirect
          - checkout
        buttonText:
          type: string
        url:
          type: string
        openNewTab:
          type: boolean
        display:
          $ref: '#/components/schemas/DisplayRule'
    QuestionOption:
      type: object
      required:
      - id
      - label
      properties:
        id:
          type: string
        label:
          type: string
        icon:
          type: string
        imageUrl:
          type: string
        points:
          type: number
          description: Adds to {{score}} when selected.
        value:
          type: string
          description: Exposed via {{variable}} for later steps.
    PaidField:
      type: object
      properties:
        feature:
          type: string
          enum:
          - file_upload
          - picture_choice
          - video_upload
          - testimonials_photo
        questionIds:
          type: array
          items:
            type: string
    ConditionV2:
      type: object
      properties:
        id:
          type: string
        left:
          type: string
          description: Literal, {{variable}} or calc(...).
        operator:
          type: string
          enum:
          - equal_to
          - not_equal_to
          - greater_than
          - greater_or_equal_than
          - less_than
          - less_or_equal_than
          - contains
        right:
          type: string
    AlertItem:
      type: object
      properties:
        id:
          type: string
        title:
          type: string
        message:
          type: string
        color:
          type: string
          description: theme|error|info|success|warning or hex.
        severity:
          type: string
          enum:
          - warning
          - info
          - success
          - error
          - custom
        iconKey:
          type: string
        highlight:
          type: boolean
        display:
          $ref: '#/components/schemas/DisplayRule'
    FormInput:
      type: object
      required:
      - title
      properties:
        title:
          type: string
        description:
          type:
          - string
          - 'null'
        slug:
          type: string
        status:
          type: string
          enum:
          - draft
          - published
          - closed
        theme:
          type: string
          description: Form theme. New forms default to amber (copper-to-amber gradient, the FoxForm default); base is the neutral graphite option.
          default: amber
          enum:
          - amber
          - base
          - midnight
          - ocean
          - sunset
          - forest
          - lavender
          - minimal
        questions:
          type: array
          items:
            $ref: '#/components/schemas/QuestionConfig'
        thank_you_message:
          type: string
        webhook_url:
          type:
          - string
          - 'null'
        show_progress_bar:
          type: boolean
        show_navigation_arrows:
          type: boolean
        email_notifications:
          type: boolean
        hide_branding:
          type: boolean
    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          example: false
        message:
          type: string
          description: Human-readable error.
        code:
          type: string
          description: Machine-readable code, e.g. PAID_FIELDS_REQUIRED, FINGERPRINT_REQUIRED.
    ListFormsResponse:
      type: object
      properties:
        success:
          type: boolean
        data:
          type: array
          items:
            $ref: '#/components/schemas/Form'
        total:
          type: integer
        page:
          type: integer
        limit:
          type: integer
    DisplayRule:
      type: object
      properties:
        enabled:
          type: boolean
        groups:
          type: array
          items:
            $ref: '#/components/schemas/ConditionGroup'
        showAfterSeconds:
          type: number
  responses:
    Success:
      description: Generic success.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/SuccessResponse'
    Error:
      description: Error.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: 'FoxForm API key (ff_live_…), generated in the dashboard under "MCP & API". Also accepted as ''Authorization: Bearer ff_live_…'' or a ''?key='' query param. Keys are scoped read or read+write.'