{
  "openapi": "3.0.3",
  "info": {
    "title": "FoxForm 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."
    },
    {
      "name": "Responses",
      "description": "Read form responses and aggregated analytics. Collection is beacon-driven."
    },
    {
      "name": "Analytics",
      "description": "Aggregated per-question statistics and CSV export."
    },
    {
      "name": "Users",
      "description": "Authenticated user profile and asset uploads."
    }
  ],
  "paths": {
    "/user/profile": {
      "get": {
        "tags": [
          "Users"
        ],
        "summary": "Get the authenticated user's profile",
        "responses": {
          "200": {
            "description": "User profile.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetUserProfileResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          }
        },
        "security": [
          {
            "ApiKey": []
          }
        ]
      }
    },
    "/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": []
          }
        ]
      },
      "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": []
          }
        ]
      }
    },
    "/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": []
          }
        ]
      },
      "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": []
          }
        ]
      },
      "delete": {
        "tags": [
          "Forms"
        ],
        "summary": "Delete a form",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Success"
          }
        },
        "security": [
          {
            "ApiKey": []
          }
        ]
      }
    },
    "/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"
          }
        }
      }
    },
    "/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": []
          }
        ]
      }
    },
    "/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": []
          }
        ]
      }
    },
    "/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": []
          }
        ]
      }
    },
    "/forms/{formId}/responses": {
      "get": {
        "tags": [
          "Responses"
        ],
        "summary": "List responses for a form",
        "parameters": [
          {
            "name": "formId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated responses.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListResponsesResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": []
          }
        ]
      }
    },
    "/forms/{formId}/export": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Export responses (CSV/XLSX)",
        "parameters": [
          {
            "name": "formId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "csv",
                "xlsx"
              ],
              "default": "csv"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Binary export.",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": []
          }
        ]
      }
    },
    "/responses": {
      "post": {
        "tags": [
          "Responses"
        ],
        "summary": "Submit a response (server-to-server)",
        "description": "Public. NOTE: the FoxForm form player does NOT call this — responses are collected via the analytics beacon and reconstructed server-side. Use this only for manual/integration submissions.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResponseInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Stored response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetResponseResponse"
                }
              }
            }
          }
        }
      }
    },
    "/responses/{responseId}": {
      "parameters": [
        {
          "name": "responseId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "tags": [
          "Responses"
        ],
        "summary": "Get a response by ID",
        "responses": {
          "200": {
            "description": "Response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetResponseResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": []
          }
        ]
      },
      "delete": {
        "tags": [
          "Responses"
        ],
        "summary": "Delete a response",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Success"
          }
        },
        "security": [
          {
            "ApiKey": []
          }
        ]
      }
    },
    "/responses/stats/aggregated": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Aggregated per-question statistics",
        "parameters": [
          {
            "name": "formId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Aggregated stats.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetAggregatedStatsResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": []
          }
        ]
      }
    }
  },
  "components": {
    "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."
      }
    },
    "responses": {
      "Success": {
        "description": "Generic success.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SuccessResponse"
            }
          }
        }
      },
      "Error": {
        "description": "Error.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "FileUpload": {
        "description": "Uploaded asset URL.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/FileUploadResponse"
            }
          }
        }
      }
    },
    "schemas": {
      "SuccessResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "message": {
            "type": "string"
          }
        }
      },
      "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."
          }
        }
      },
      "FileUploadResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "object",
            "properties": {
              "url": {
                "type": "string",
                "format": "uri"
              }
            }
          },
          "message": {
            "type": "string"
          }
        }
      },
      "Base64Upload": {
        "type": "object",
        "required": [
          "file"
        ],
        "properties": {
          "file": {
            "type": "string",
            "description": "Base64-encoded file content (without the data: prefix)."
          },
          "filename": {
            "type": "string"
          },
          "contentType": {
            "type": "string"
          }
        }
      },
      "LoginRequest": {
        "type": "object",
        "required": [
          "email",
          "password"
        ],
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "password": {
            "type": "string",
            "format": "password"
          }
        }
      },
      "SignupRequest": {
        "type": "object",
        "required": [
          "email",
          "password"
        ],
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "password": {
            "type": "string",
            "format": "password"
          },
          "full_name": {
            "type": "string"
          },
          "utm_source": {
            "type": "string"
          },
          "utm_medium": {
            "type": "string"
          },
          "utm_campaign": {
            "type": "string"
          },
          "utm_term": {
            "type": "string"
          },
          "utm_content": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "description": "Partnership source, e.g. 'panda' (drives Starter/coupon eligibility)."
          },
          "visitorId": {
            "type": "string"
          },
          "requestId": {
            "type": "string"
          }
        }
      },
      "AuthResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "email": {
                "type": "string"
              },
              "full_name": {
                "type": "string"
              },
              "token": {
                "type": "string",
                "description": "Cognito idToken (use as Bearer)."
              },
              "accessToken": {
                "type": "string"
              },
              "refreshToken": {
                "type": "string"
              },
              "needsConfirmation": {
                "type": "boolean"
              }
            }
          },
          "message": {
            "type": "string"
          }
        }
      },
      "UserProfile": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "full_name": {
            "type": "string"
          },
          "avatar_url": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "organization_id": {
            "type": "string",
            "nullable": true
          },
          "organization": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Organization"
              }
            ],
            "nullable": true
          },
          "account_status": {
            "type": "string",
            "enum": [
              "active",
              "blocked"
            ]
          },
          "source": {
            "type": "string",
            "description": "Partnership source, e.g. 'panda'."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "GetUserProfileResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/UserProfile"
          }
        }
      },
      "UpdateUserProfileRequest": {
        "type": "object",
        "properties": {
          "full_name": {
            "type": "string"
          },
          "avatar_url": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "description": "Write-once partnership tag (only allowed value: 'panda')."
          }
        }
      },
      "Organization": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "vat_number": {
            "type": "string"
          },
          "address_line1": {
            "type": "string"
          },
          "address_line2": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "state": {
            "type": "string"
          },
          "postal_code": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "logo_url": {
            "type": "string"
          },
          "owner_id": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CreateOrganizationRequest": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "vat_number": {
            "type": "string"
          },
          "address_line1": {
            "type": "string"
          },
          "address_line2": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "state": {
            "type": "string"
          },
          "postal_code": {
            "type": "string"
          },
          "country": {
            "type": "string"
          }
        }
      },
      "UpdateOrganizationRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "vat_number": {
            "type": "string"
          },
          "address_line1": {
            "type": "string"
          },
          "address_line2": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "state": {
            "type": "string"
          },
          "postal_code": {
            "type": "string"
          },
          "country": {
            "type": "string"
          }
        }
      },
      "GetOrganizationResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Organization"
              }
            ],
            "nullable": true
          },
          "message": {
            "type": "string"
          }
        }
      },
      "OrganizationResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/Organization"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "OnboardingState": {
        "type": "object",
        "properties": {
          "started_at": {
            "type": "string",
            "format": "date-time"
          },
          "completed_at": {
            "type": "string",
            "format": "date-time"
          },
          "email_verified": {
            "type": "boolean"
          },
          "questions_completed": {
            "type": "boolean"
          },
          "form_created": {
            "type": "boolean"
          },
          "form_published": {
            "type": "boolean"
          },
          "answers": {
            "type": "object",
            "properties": {
              "useCase": {
                "type": "string"
              },
              "previousTool": {
                "type": "string"
              },
              "source": {
                "type": "string"
              },
              "volume": {
                "type": "string"
              }
            }
          },
          "discount_used": {
            "type": "boolean"
          },
          "discount_used_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "GDriveStatus": {
        "type": "object",
        "properties": {
          "connected": {
            "type": "boolean"
          },
          "folderId": {
            "type": "string",
            "nullable": true
          },
          "folderName": {
            "type": "string",
            "nullable": true
          },
          "connectedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Form": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "user_id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "slug": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "published",
              "closed"
            ]
          },
          "theme": {
            "type": "string",
            "enum": [
              "midnight",
              "ocean",
              "sunset",
              "forest",
              "lavender",
              "minimal"
            ]
          },
          "questions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/QuestionConfig"
            }
          },
          "thank_you_message": {
            "type": "string"
          },
          "webhook_url": {
            "type": "string",
            "nullable": true
          },
          "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"
          }
        }
      },
      "FormInput": {
        "type": "object",
        "required": [
          "title"
        ],
        "properties": {
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "slug": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "published",
              "closed"
            ]
          },
          "theme": {
            "type": "string",
            "enum": [
              "midnight",
              "ocean",
              "sunset",
              "forest",
              "lavender",
              "minimal"
            ]
          },
          "questions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/QuestionConfig"
            }
          },
          "thank_you_message": {
            "type": "string"
          },
          "webhook_url": {
            "type": "string",
            "nullable": true
          },
          "show_progress_bar": {
            "type": "boolean"
          },
          "show_navigation_arrows": {
            "type": "boolean"
          },
          "email_notifications": {
            "type": "boolean"
          },
          "hide_branding": {
            "type": "boolean"
          }
        }
      },
      "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"
          },
          "buttonLink": {
            "type": "string"
          },
          "buttonOpenNewTab": {
            "type": "boolean"
          },
          "socialEnabled": {
            "type": "boolean"
          },
          "socialLinks": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "platform": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "iconUrl": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "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"
        ]
      },
      "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."
          }
        }
      },
      "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"
          }
        }
      },
      "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"
          }
        }
      },
      "NavigationTarget": {
        "type": "string",
        "enum": [
          "next_screen",
          "previous_screen",
          "specific_screen",
          "end_form"
        ]
      },
      "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"
              }
            }
          }
        }
      },
      "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"
          }
        }
      },
      "DisplayRule": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "groups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConditionGroup"
            }
          },
          "showAfterSeconds": {
            "type": "number"
          }
        }
      },
      "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"
          }
        }
      },
      "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"
          }
        }
      },
      "ArgumentItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "imageUrl": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "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"
          }
        }
      },
      "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"
          }
        }
      },
      "ButtonAction": {
        "type": "object",
        "properties": {
          "type": {
            "$ref": "#/components/schemas/NavigationTarget"
          },
          "targetScreenId": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "openNewTab": {
            "type": "boolean"
          }
        }
      },
      "ListFormsResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Form"
            }
          },
          "total": {
            "type": "integer"
          },
          "page": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          }
        }
      },
      "GetFormResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/Form"
          }
        }
      },
      "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"
                }
              }
            }
          }
        }
      },
      "PaidField": {
        "type": "object",
        "properties": {
          "feature": {
            "type": "string",
            "enum": [
              "file_upload",
              "picture_choice",
              "video_upload",
              "testimonials_photo"
            ]
          },
          "questionIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "Response": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "form_id": {
            "type": "string"
          },
          "answers": {
            "type": "object",
            "additionalProperties": true
          },
          "submitted_at": {
            "type": "string",
            "format": "date-time"
          },
          "session_id": {
            "type": "string",
            "description": "Beacon session id."
          }
        }
      },
      "ResponseInput": {
        "type": "object",
        "required": [
          "form_id",
          "answers"
        ],
        "properties": {
          "form_id": {
            "type": "string"
          },
          "answers": {
            "type": "object",
            "additionalProperties": true
          },
          "session_id": {
            "type": "string"
          }
        }
      },
      "ListResponsesResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Response"
            }
          },
          "total": {
            "type": "integer"
          },
          "page": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          }
        }
      },
      "GetResponseResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/Response"
          }
        }
      },
      "GetAggregatedStatsResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/AggregatedStats"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "AggregatedStats": {
        "type": "object",
        "properties": {
          "form_id": {
            "type": "string"
          },
          "overview": {
            "type": "object",
            "properties": {
              "total_responses": {
                "type": "integer"
              },
              "first_response_at": {
                "type": "string",
                "nullable": true
              },
              "last_response_at": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "timeline": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "date": {
                  "type": "string"
                },
                "count": {
                  "type": "integer"
                }
              }
            }
          },
          "questions": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "question_id": {
                  "type": "string"
                },
                "question_type": {
                  "$ref": "#/components/schemas/QuestionType"
                },
                "question_title": {
                  "type": "string"
                },
                "data": {
                  "type": "object",
                  "description": "One of choice/boolean/numeric/date/text/file stats.",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      },
      "SubscriptionInfo": {
        "type": "object",
        "properties": {
          "plan": {
            "type": "string",
            "enum": [
              "free",
              "starter",
              "pro",
              "gold"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "free",
              "active",
              "past_due",
              "canceled",
              "trialing"
            ]
          },
          "hasActiveSubscription": {
            "type": "boolean"
          },
          "currentPeriodEnd": {
            "type": "string",
            "format": "date-time"
          },
          "freeUntil": {
            "type": "string",
            "format": "date-time",
            "description": "Starter PANDA1YEAR coupon end (created_at + 12 months)."
          },
          "cancelAtPeriodEnd": {
            "type": "boolean"
          }
        }
      },
      "Plan": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "price": {
            "type": "number"
          },
          "currency": {
            "type": "string"
          },
          "interval": {
            "type": "string"
          },
          "features": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "PaymentMethod": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "brand": {
            "type": "string"
          },
          "last4": {
            "type": "string"
          },
          "expMonth": {
            "type": "integer"
          },
          "expYear": {
            "type": "integer"
          },
          "isDefault": {
            "type": "boolean"
          }
        }
      },
      "Invoice": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "nullable": true
          },
          "amount": {
            "type": "number"
          },
          "currency": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "paid",
              "open",
              "draft",
              "void",
              "uncollectible"
            ]
          },
          "invoicePdf": {
            "type": "string",
            "nullable": true
          },
          "hostedInvoiceUrl": {
            "type": "string",
            "nullable": true
          },
          "periodStart": {
            "type": "string",
            "nullable": true
          },
          "periodEnd": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "UsageData": {
        "type": "object",
        "properties": {
          "responses": {
            "type": "object",
            "properties": {
              "used": {
                "type": "integer"
              },
              "limit": {
                "type": "integer"
              },
              "unlimited": {
                "type": "boolean"
              }
            }
          },
          "period": {
            "type": "object",
            "properties": {
              "start": {
                "type": "string"
              },
              "end": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  }
}