# Examples (/examples) This guide outlines various methods for submitting the form. You can access your form's endpoint by navigating to the following path:
[dashboard](https://vexrun.com/dashboard) -> `Forms` -> `"Any Form"` -> `Setup`.
HTML [#html] After clicking `Submit` the user will be redirected to the default "Thank You" page or a custom URL if configured. For a detailed overview of potential responses from your form's endpoint, refer to the documentation [here](/http-api/submissions/create-submission). Remember to include `enctype="multipart/form-data"` in your form element. ```html title="HTML"
``` JSON using JavaScript [#json-using-javascript] For a detailed overview of potential responses from your form's endpoint, refer to the documentation [here](/http-api/submissions/create-submission). Uploading files isn't supported in JSON. ```js title="JavaScript" const data = { email: "test@vexrun.com", name: "John Doe", message: "Hello!", }; const res = await fetch("{your_form_endpoint}", { method: "POST", headers: { Accept: "application/json", "Content-Type": "application/json", }, body: JSON.stringify(data), }); const json = await res.json(); console.log(json); ``` FormData using JavaScript [#formdata-using-javascript] For a detailed overview of potential responses from your form's endpoint, refer to the documentation [here](/http-api/submissions/create-submission). ```js title="JavaScript" const data = new FormData(); data.append("email", "test@vexrun.com"); data.append("name", "John Doe"); data.append("message", "Hello!"); const file = document.querySelector("input[name=file]").files[0]; data.append("file", file); const res = await fetch("{your_form_endpoint}", { method: "POST", headers: { Accept: "application/json", }, body: data, }); const json = await res.json(); console.log(json); ``` Validation [#validation] This example demonstrates how to use built-in browser validation and JavaScript to ensure data integrity before submitting a form. This example includes custom file size validation, as it's not supported by browsers out of the box. Used APIs that you might not be familiar with: * form element's [novalidate](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#novalidate) attribute * HTMLFormElement.[reportValidity()](https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/reportValidity) * HTMLInputElement.[setCustomValidity()](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setCustomValidity) * [FormData](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest_API/Using_FormData_Objects) The browser supports many attributes that you can use to validate your forms. This [article](https://developer.mozilla.org/en-US/docs/Learn/Forms/Form_validation) is a great resource to learn more about client-side form validation.
Available attributes: [type](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#input_types), [required](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/required), [minlength](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/minlength), [maxlength](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/maxlength), [min](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/min), [max](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/max), [pattern](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/pattern).
```html title="HTML"
``` ```js title="JavaScript" const maxFileSize = 10_000_000; // 10 MB const form = document.querySelector("#my-form"); const fileField = document.querySelector("#my-file-field"); form.addEventListener("submit", async (event) => { // Prevents the default form submission behavior event.preventDefault(); const file = fileField.files?.[0]; if (file && file.size > maxFileSize) { fileField.setCustomValidity(`File is larger than ${maxFileSize / 1_000_000} MB.`); } else { fileField.setCustomValidity(""); } // form.reportValidity will validate all inputs based on their // attributes (e.g. required, minlength). Unfortunately it doesn't // support validating file size, hence the above code. const isValid = form.reportValidity(); if (isValid === false) { return; } // All fields are valid const data = new FormData(form); const res = await fetch(form.action, { method: "POST", headers: { Accept: "application/json", }, body: data, }); console.log(await res.json()); }); ``` --- # Introduction (/) Welcome to Vexrun Forms, your all-in-one solution for effortless HTML form submissions. \ Vexrun Forms is a forms backend designed to streamline the process of managing form submissions for developers and non-developers alike. This documentation will guide you through the key features, customization options, and HTTP API. Getting started [#getting-started] HTTP API Endpoints [#http-api-endpoints] {/* } title="Schema" href="/http-api/schema/get-form-schema" /> */} --- # Authentication (/http-api/authentication) To access most of the endpoints in the Vexrun API, you need to authenticate your requests. \ This involves using your team's unique `ID` and `API key`. You can find these credentials in the "API" tab of your [dashboard](https://vexrun.com/dashboard). Making Authenticated Requests [#making-authenticated-requests] To interact with any endpoint that requires authentication, you must include the `x-team-id` and `x-api-key` headers in your request. Below is an example of how you can structure an authenticated request: ```js const response = await fetch("https://forms.vexrun.com/v1/forms", { headers: { "x-team-id": "...", "x-api-key": "...", }, }); ``` ```sh curl 'https://forms.vexrun.com/v1/forms' \ -H 'x-team-id: ...' \ -H 'x-api-key: ...' ``` Regenerate Your API Key [#regenerate-your-api-key] For security and access control purposes, it's crucial to regenerate your API key if you have any concerns about its security. Never share or disclose your API key under any circumstances. If you suspect that your key's security has been compromised, take immediate action by clicking on the `Regenerate API Key` option to update it. --- # Overview (/http-api) You can access your form's ID by navigating to the following path:
[dashboard](https://vexrun.com/dashboard) -> `Forms` -> `"Any Form"` -> `Setup`.
If you're looking to submit data to a form, you should use the [Create Submission](/http-api/submissions/create-submission) endpoint. {/* } title="Schema" href="/http-api/schema/get-form-schema" /> */} --- # Submission Data Limits (/advanced/submission-data-limits) The following limits apply to all submissions. Any submission that exceeds a limit will be rejected with a [413 Payload Too Large](/http-api/submissions/create-submission) error. {
Limit Max Value Description
Field Name 100 B Maximum length of a field name (JSON key or `name` attribute in an input).
Property Count 1000 Maximum number of fields/properties per submission.
File Count 10 Maximum number of files that can be uploaded in a single submission.
Submission Size 100 KB Maximum total size of all non-file data after being stringified as JSON.
File Upload Limit 100 MB Combined size limit for all uploaded files per submission.
} --- # Get File (/http-api/files/get-file) - GET /v1/forms/{form_id}/submissions/{submission_id}/files/{file_id} Retrieve a file by ID. You should always excercise extreme caution when working with files that don't come from a trusted source. --- # List All Forms (/http-api/forms/list-all-forms) - GET /v1/forms Returns an array of forms created by your team. --- # Create Form (/http-api/forms/create-form) - POST /v1/forms Creates new form. --- # Create Submission (/http-api/submissions/create-submission) - POST /v1/forms/{form_id} Submits data to a form. View [examples](/examples). ### Request Formats This endpoint accepts submissions in two formats: - **application/json** - **multipart/form-data** #### Special Handling for multipart/form-data - If a field named `$` is present, all other non-file fields are ignored. - If `$` contains a valid stringified JSON object, it will be parsed and used as the submission data. - If `$` contains any other value, it will be ignored. ### Common Errors We have separated common errors to `422` (`303` if you are using `Accept: text/html`) response to help you better handle them. Here is a breakdown of all common error codes: | Code | Description | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | file_storage_limit_reached | Your team has reached its file storage limit. | | form_disabled | The form is currently disabled. You can enable or disable the form in the dashboard or by using this [endpoint](/http-api/forms/update-form). | | no_data | No data was submitted. | | rate_limit | The rate limit has been exceeded. Please wait at least 10 seconds before submitting another form from the same IP address. | | submission_limit_reached | Configured form `limit` has been reached or your team has reached the total submission limit counted across all forms it owns. | | validation_error | The submission did not pass validation. (Reserved for future use.) | --- # Update Form (/http-api/forms/update-form) - PATCH /v1/forms/{form_id} Partially updates a form. --- # Delete Form (/http-api/forms/delete-form) - DELETE /v1/forms/{form_id} Deletes a form together with all submissions. This action is irreversible. --- # Duplicate Form (/http-api/forms/duplicate-form) - POST /v1/forms/{form_id}/duplicate Duplicates an existing form, copying its configuration. The following properties get copied to the duplicated form: - name - is_enabled - limit - honeypot_field - emails - redirect_url - success_title - success_message - schema --- # Get Form Overview (/http-api/forms/get-form-overview) - GET /v1/forms/{form_id}/overview Returns public information about a form. This endpoint does not require authentication. --- # View Form Analytics (/http-api/analytics/view-form-analytics) - GET /v1/forms/{form_id}/analytics Returns an array of analytics data for the form based on the provided date range. --- # Get Form Schema (/http-api/schema/get-form-schema) - GET /v1/forms/{form_id}/schema Returns the schema of a form along with its version. --- # Delete Form Schema (/http-api/schema/delete-form-schema) - DELETE /v1/forms/{form_id}/schema Deletes the form schema. --- # Set Form Schema (/http-api/schema/set-form-schema) - PUT /v1/forms/{form_id}/schema Creates a new form schema or replaces an existing one. --- # List Many Submissions (/http-api/submissions/list-many-submissions) - GET /v1/forms/{form_id}/submissions Retrieves multiple submissions for a specified form. ### Pagination This endpoint supports two pagination strategies: #### Offset-based pagination - Use `limit` and `offset` to navigate through pages #### Cursor-based pagination - Use `cursor` with the ID of the last submission from the previous page - You may set `offset=1` to exclude the cursor submission from results - Provides consistent results even when new submissions are received **Note:** When using `search`, `offset` is limited to `1`. Use cursor-based pagination to navigate through search results. --- # Get Submission (/http-api/submissions/get-submission) - GET /v1/forms/{form_id}/submissions/{submission_id} Get form submission by ID. --- # Delete Submission (/http-api/submissions/delete-submission) - DELETE /v1/forms/{form_id}/submissions/{submission_id} Deletes a submission together with all files attached to it. This action is irreversible. --- # Get Usage Information (/http-api/usage/get-usage-information) - GET /v1/usage Usage may be cached for up to 60 seconds. This endpoint is primarily used for internal purposes to present data in the [dashboard](https://vexrun.com/dashboard). However, documentation is provided in case you have an external use case for it. --- # OpenAPI schema: ```json { "openapi": "3.2.0", "servers": [ { "url": "https://forms.vexrun.com", "description": "Vexrun Forms" } ], "info": { "version": "2026-04-07", "title": "Vexrun Forms API", "description": "https://docs.vexrun.com", "termsOfService": "https://vexrun.com/terms-of-service" }, "paths": { "/v1/forms/{form_id}/submissions/{submission_id}/files/{file_id}": { "get": { "summary": "Get File", "description": "Retrieve a file by ID.\n\nYou should always excercise extreme caution when working with files that don't come from a trusted source.", "tags": [ "Files" ], "operationId": "files/get-file", "parameters": [ { "name": "form_id", "in": "path", "schema": { "type": "string" }, "required": true }, { "name": "submission_id", "in": "path", "schema": { "type": "string" }, "required": true }, { "name": "file_id", "in": "path", "schema": { "type": "string" }, "required": true } ], "responses": { "200": { "description": "", "content": { "*/*": { "schema": { "type": "string", "format": "binary" } } } }, "default": { "description": "Generic error (e.g. invalid auth).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } } }, "security": [ { "x-api-key": [], "x-team-id": [] } ] } }, "/v1/forms": { "get": { "summary": "List All Forms", "description": "Returns an array of forms created by your team.", "tags": [ "Forms" ], "operationId": "forms/list-all-forms", "parameters": [], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Form" } } } } }, "default": { "description": "Generic error (e.g. invalid auth).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } } }, "security": [ { "x-api-key": [], "x-team-id": [] } ] }, "post": { "summary": "Create Form", "description": "Creates new form.", "tags": [ "Forms" ], "operationId": "forms/create-form", "parameters": [], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Form.Create" } } }, "required": true }, "responses": { "201": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Form" } } } }, "400": { "description": "Input validation error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiValidationError" } } } }, "default": { "description": "Generic error (e.g. invalid auth).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } } }, "security": [ { "x-api-key": [], "x-team-id": [] } ] } }, "/v1/forms/{form_id}": { "patch": { "summary": "Update Form", "description": "Partially updates a form.", "tags": [ "Forms" ], "operationId": "forms/update-form", "parameters": [ { "name": "form_id", "in": "path", "schema": { "type": "string" }, "required": true } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Form.Update" } } }, "required": true }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Form" } } } }, "400": { "description": "Input validation error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiValidationError" } } } }, "default": { "description": "Generic error (e.g. invalid auth).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } } }, "security": [ { "x-api-key": [], "x-team-id": [] } ] }, "delete": { "summary": "Delete Form", "description": "Deletes a form together with all submissions. This action is irreversible.", "tags": [ "Forms" ], "operationId": "forms/delete-form", "parameters": [ { "name": "form_id", "in": "path", "schema": { "type": "string" }, "required": true } ], "responses": { "204": { "description": "", "content": { "application/json": {} } }, "default": { "description": "Generic error (e.g. invalid auth).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } } }, "security": [ { "x-api-key": [], "x-team-id": [] } ] }, "post": { "summary": "Create Submission", "description": "Submits data to a form. View [examples](/examples).\n\n### Request Formats\n\nThis endpoint accepts submissions in two formats:\n\n- **application/json**\n- **multipart/form-data**\n\n#### Special Handling for multipart/form-data\n\n- If a field named `$` is present, all other non-file fields are ignored.\n- If `$` contains a valid stringified JSON object, it will be parsed and used as the submission data.\n- If `$` contains any other value, it will be ignored.\n\n### Common Errors\n\nWe have separated common errors to `422` (`303` if you are using `Accept: text/html`) response to help you better handle them.\n\nHere is a breakdown of all common error codes:\n\n| Code | Description |\n| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |\n| file_storage_limit_reached | Your team has reached its file storage limit. |\n| form_disabled | The form is currently disabled. You can enable or disable the form in the dashboard or by using this [endpoint](/http-api/forms/update-form). |\n| no_data | No data was submitted. |\n| rate_limit | The rate limit has been exceeded. Please wait at least 10 seconds before submitting another form from the same IP address. |\n| submission_limit_reached | Configured form `limit` has been reached or your team has reached the total submission limit counted across all forms it owns. |\n| validation_error | The submission did not pass validation. (Reserved for future use.) |", "tags": [ "Submissions" ], "operationId": "submissions/create-submission", "parameters": [ { "name": "form_id", "in": "path", "schema": { "type": "string" }, "required": true }, { "in": "header", "name": "Accept", "description": "Specifies preferred response format: `application/json` for JSON or `text/html` for a redirect.", "schema": { "type": "string" } } ], "responses": { "201": { "description": "Used when accept header is `application/json` or submitted data is of type: `application/json` and accept header is not set.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SubmitForm.Success" } } } }, "303": { "description": "Redirects the user to the configured `redirect_url`.\nIf the submission isn't successful, the user will still be redirected, and two query parameters will be appended to the URL:\n- **message**: User-friendly error message\n- **error**: [Standardized error code](/http-api/submissions/create-submission#common-errors)\n\nUsed when accept header is `text/html` or submitted data is of type: `multipart/form-data` and accept header is not set." }, "413": { "description": "Submission Data Limit reached. [Read more](/advanced/submission-data-limits).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SubmitForm.ContentTooLarge" } } } }, "422": { "description": "One of [common errors](/http-api/submissions/create-submission#common-errors) has occured while saving submission.\n\nUsed when accept header is `application/json` or submitted data is of type: `application/json` and accept header is not set.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SubmitForm.CommonError" } } } }, "default": { "description": "Generic error (e.g. invalid auth).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } } } } }, "/v1/forms/{form_id}/duplicate": { "post": { "summary": "Duplicate Form", "description": "Duplicates an existing form, copying its configuration.\n\nThe following properties get copied to the duplicated form:\n- name\n- is_enabled\n- limit\n- honeypot_field\n- emails\n- redirect_url\n- success_title\n- success_message\n- schema", "tags": [ "Forms" ], "operationId": "forms/duplicate-form", "parameters": [ { "name": "form_id", "in": "path", "schema": { "type": "string" }, "required": true } ], "responses": { "201": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Form" } } } }, "default": { "description": "Generic error (e.g. invalid auth).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } } }, "security": [ { "x-api-key": [], "x-team-id": [] } ] } }, "/v1/forms/{form_id}/overview": { "get": { "summary": "Get Form Overview", "description": "Returns public information about a form.\n\nThis endpoint does not require authentication.", "tags": [ "Forms" ], "operationId": "forms/get-form-overview", "parameters": [ { "name": "form_id", "in": "path", "schema": { "type": "string" }, "required": true } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Form.PublicOverview" } } } }, "default": { "description": "Generic error (e.g. invalid auth).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } } } } }, "/v1/forms/{form_id}/analytics": { "get": { "summary": "View Form Analytics", "description": "Returns an array of analytics data for the form based on the provided date range.", "tags": [ "Analytics" ], "operationId": "analytics/view-form-analytics", "parameters": [ { "name": "form_id", "in": "path", "schema": { "type": "string" }, "required": true }, { "name": "start_date", "in": "query", "schema": { "type": "string", "format": "date" }, "required": true }, { "name": "end_date", "in": "query", "schema": { "type": "string", "format": "date" }, "required": true } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/FormAnalytics" } } } } }, "400": { "description": "Input validation error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiValidationError" } } } }, "default": { "description": "Generic error (e.g. invalid auth).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } } }, "security": [ { "x-api-key": [], "x-team-id": [] } ] } }, "/v1/forms/{form_id}/schema": { "get": { "summary": "Get Form Schema", "description": "Returns the schema of a form along with its version.", "tags": [ "Schema" ], "operationId": "schema/get-form-schema", "parameters": [ { "name": "form_id", "in": "path", "schema": { "type": "string" }, "required": true } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FormSchemaV1" } } } }, "404": { "description": "Form doesn't exist or doesn't have a schema", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } }, "default": { "description": "Generic error (e.g. invalid auth).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } } }, "security": [ { "x-api-key": [], "x-team-id": [] } ] }, "put": { "summary": "Set Form Schema", "description": "Creates a new form schema or replaces an existing one.", "tags": [ "Schema" ], "operationId": "schema/set-form-schema", "parameters": [ { "name": "form_id", "in": "path", "schema": { "type": "string" }, "required": true } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FormSchemaV1" } } }, "required": true }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FormSchemaV1" } } } }, "400": { "description": "Input validation error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiValidationError" } } } }, "default": { "description": "Generic error (e.g. invalid auth).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } } }, "security": [ { "x-api-key": [], "x-team-id": [] } ] }, "delete": { "summary": "Delete Form Schema", "description": "Deletes the form schema.", "tags": [ "Schema" ], "operationId": "schema/delete-form-schema", "parameters": [ { "name": "form_id", "in": "path", "schema": { "type": "string" }, "required": true } ], "responses": { "204": { "description": "", "content": { "application/json": {} } }, "404": { "description": "Form doesn't exist or doesn't have a schema", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } }, "default": { "description": "Generic error (e.g. invalid auth).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } } }, "security": [ { "x-api-key": [], "x-team-id": [] } ] } }, "/v1/forms/{form_id}/submissions": { "get": { "summary": "List Many Submissions", "description": "Retrieves multiple submissions for a specified form.\n\n### Pagination\n\nThis endpoint supports two pagination strategies:\n\n#### Offset-based pagination\n\n- Use `limit` and `offset` to navigate through pages\n\n#### Cursor-based pagination\n\n- Use `cursor` with the ID of the last submission from the previous page\n- You may set `offset=1` to exclude the cursor submission from results\n- Provides consistent results even when new submissions are received\n\n**Note:** When using `search`, `offset` is limited to `1`. Use cursor-based pagination to navigate through search results.", "tags": [ "Submissions" ], "operationId": "submissions/list-many-submissions", "parameters": [ { "name": "form_id", "in": "path", "schema": { "type": "string" }, "required": true }, { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 500, "default": 100 }, "required": false, "description": "Maximum number of submissions to return." }, { "name": "offset", "in": "query", "schema": { "type": "integer", "minimum": 0, "default": 0 }, "required": false, "description": "Number of submissions to skip. Limited to `1` when using `search`." }, { "name": "cursor", "in": "query", "schema": { "type": "string", "minLength": 24, "maxLength": 24 }, "required": false, "description": "Submission ID to use as the starting point for pagination (inclusive).\n\nUse cursor-based pagination when:\n- Navigating through search results\n- Working with large datasets\n- You need consistent results across pages\n\nTo get the next page, use the `id` of the last submission from the current page.\n\nSet `offset=1` to exclude the cursor submission itself from results." }, { "name": "sort", "in": "query", "schema": { "oneOf": [ { "const": "ASC", "title": "\"ASC\"" }, { "const": "DESC", "title": "\"DESC\"" } ] }, "required": false, "description": "Sort order by creation date (created_at).\n- `DESC`: Newest submissions first (default)\n- `ASC`: Oldest submissions first" }, { "name": "search", "in": "query", "schema": { "type": "string", "minLength": 1, "maxLength": 100 }, "required": false, "description": "Search term to filter submissions.\n\nPerforms substring matching (case-insensitive) across submission data.\n\nWhen provided, offset-based pagination is limited to `1`.\nUse cursor-based pagination to navigate through search results." } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PaginatedSubmission" } } } }, "400": { "description": "Input validation error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiValidationError" } } } }, "default": { "description": "Generic error (e.g. invalid auth).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } } }, "security": [ { "x-api-key": [], "x-team-id": [] } ] } }, "/v1/forms/{form_id}/submissions/{submission_id}": { "get": { "summary": "Get Submission", "description": "Get form submission by ID.", "tags": [ "Submissions" ], "operationId": "submissions/get-submission", "parameters": [ { "name": "form_id", "in": "path", "schema": { "type": "string" }, "required": true }, { "name": "submission_id", "in": "path", "schema": { "type": "string" }, "required": true } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Submission" } } } }, "default": { "description": "Generic error (e.g. invalid auth).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } } }, "security": [ { "x-api-key": [], "x-team-id": [] } ] }, "delete": { "summary": "Delete Submission", "description": "Deletes a submission together with all files attached to it. This action is irreversible.", "tags": [ "Submissions" ], "operationId": "submissions/delete-submission", "parameters": [ { "name": "form_id", "in": "path", "schema": { "type": "string" }, "required": true }, { "name": "submission_id", "in": "path", "schema": { "type": "string" }, "required": true } ], "responses": { "204": { "description": "", "content": { "application/json": {} } }, "default": { "description": "Generic error (e.g. invalid auth).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } } }, "security": [ { "x-api-key": [], "x-team-id": [] } ] } }, "/v1/usage": { "get": { "summary": "Get Usage Information", "description": "Usage may be cached for up to 60 seconds.\n\nThis endpoint is primarily used for internal purposes to present data in the [dashboard](https://vexrun.com/dashboard). However, documentation is provided in case you have an external use case for it.", "tags": [ "Usage" ], "operationId": "usage/get-usage-information", "parameters": [], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Usage" } } } }, "default": { "description": "Generic error (e.g. invalid auth).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } } } }, "security": [ { "x-api-key": [], "x-team-id": [] } ] } } }, "components": { "schemas": { "Form": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string", "minLength": 2, "maxLength": 50 }, "is_enabled": { "type": "boolean", "description": "Whether the form is enabled or not, disabled forms will not accept new submissions." }, "limit": { "oneOf": [ { "type": "null" }, { "type": "integer", "minimum": 1, "maximum": 100000000 } ], "description": "Number of submissions this form will accept before rejecting new ones." }, "honeypot_field": { "oneOf": [ { "type": "null" }, { "type": "string", "minLength": 1, "maxLength": 100 } ], "description": "Honeypot field, if filled, submission will be silently discarded." }, "redirect_url": { "oneOf": [ { "type": "null" }, { "type": "string", "format": "url" } ], "description": "The URL to redirect to after a successful submission." }, "success_title": { "type": "string", "minLength": 2, "maxLength": 50, "description": "Shown on \"Thank You\" page" }, "success_message": { "type": "string", "minLength": 2, "maxLength": 200, "description": "Shown on \"Thank You\" page" }, "created_at": { "type": "number", "description": "Measured in milliseconds since the Unix epoch." }, "last_submission_at": { "oneOf": [ { "type": "null" }, { "type": "number" } ], "description": "Measured in milliseconds since the Unix epoch." } }, "required": [ "id", "name", "is_enabled", "limit", "honeypot_field", "redirect_url", "success_title", "success_message", "created_at", "last_submission_at" ] }, "Form.Create": { "type": "object", "properties": { "name": { "type": "string", "minLength": 2, "maxLength": 50 }, "is_enabled": { "type": "boolean", "description": "Whether the form is enabled or not, disabled forms will not accept new submissions." }, "limit": { "oneOf": [ { "type": "null" }, { "type": "integer", "minimum": 1, "maximum": 100000000 } ], "description": "Number of submissions this form will accept before rejecting new ones." }, "honeypot_field": { "oneOf": [ { "type": "null" }, { "type": "string", "minLength": 1, "maxLength": 100 } ], "description": "Honeypot field, if filled, submission will be silently discarded." }, "redirect_url": { "oneOf": [ { "type": "null" }, { "type": "string", "format": "url" } ], "description": "The URL to redirect to after a successful submission." }, "success_title": { "type": "string", "minLength": 2, "maxLength": 50, "description": "Shown on \"Thank You\" page" }, "success_message": { "type": "string", "minLength": 2, "maxLength": 200, "description": "Shown on \"Thank You\" page" } }, "required": [ "name", "is_enabled", "limit", "honeypot_field", "redirect_url", "success_title", "success_message" ] }, "Form.Update": { "type": "object", "properties": { "name": { "type": "string", "minLength": 2, "maxLength": 50 }, "is_enabled": { "type": "boolean", "description": "Whether the form is enabled or not, disabled forms will not accept new submissions." }, "limit": { "oneOf": [ { "type": "null" }, { "type": "integer", "minimum": 1, "maximum": 100000000 } ], "description": "Number of submissions this form will accept before rejecting new ones." }, "honeypot_field": { "oneOf": [ { "type": "null" }, { "type": "string", "minLength": 1, "maxLength": 100 } ], "description": "Honeypot field, if filled, submission will be silently discarded." }, "redirect_url": { "oneOf": [ { "type": "null" }, { "type": "string", "format": "url" } ], "description": "The URL to redirect to after a successful submission." }, "success_title": { "type": "string", "minLength": 2, "maxLength": 50, "description": "Shown on \"Thank You\" page" }, "success_message": { "type": "string", "minLength": 2, "maxLength": 200, "description": "Shown on \"Thank You\" page" } }, "required": [] }, "SubmitForm.Success": { "type": "object", "properties": { "success_title": { "type": "string" }, "success_message": { "type": "string" }, "redirect_url": { "type": "string", "description": "Default redirect URL or configured redirect_url." } }, "required": [ "success_title", "success_message", "redirect_url" ] }, "SubmitForm.ContentTooLarge": { "type": "object", "properties": { "message": { "type": "string" } }, "required": [ "message" ] }, "SubmitForm.CommonError": { "type": "object", "properties": { "message": { "type": "string", "description": "User-friendly error message." }, "error": { "oneOf": [ { "const": "form_disabled", "title": "\"form_disabled\"" }, { "const": "submission_limit_reached", "title": "\"submission_limit_reached\"" }, { "const": "file_storage_limit_reached", "title": "\"file_storage_limit_reached\"" }, { "const": "no_data", "title": "\"no_data\"" }, { "const": "rate_limit", "title": "\"rate_limit\"" }, { "const": "validation_error", "title": "\"validation_error\"" } ], "description": "Standardized error code." } }, "required": [ "message", "error" ] }, "Form.PublicOverview": { "type": "object", "properties": { "status": { "oneOf": [ { "const": "open", "title": "\"open\"" }, { "const": "form_disabled", "title": "\"form_disabled\"" }, { "const": "submission_limit_reached", "title": "\"submission_limit_reached\"" } ], "description": "Indicates the current state of the form:\n- \"open\": The form is accepting new submissions.\n- \"form_disabled\": The form has been disabled and is not accepting submissions.\n- \"submission_limit_reached\": The form has reached its submission limit and can no longer accept new submissions." }, "schema": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/FormSchemaV1" } ], "description": "Reserved for future use. Currently always `null`." }, "show_branding": { "type": "boolean", "description": "Whether vexrun branding should be shown." }, "redirect_url": { "oneOf": [ { "type": "null" }, { "type": "string", "format": "url" } ], "description": "The URL to redirect to after a successful submission." }, "success_title": { "type": "string", "minLength": 2, "maxLength": 50, "description": "Shown on \"Thank You\" page" }, "success_message": { "type": "string", "minLength": 2, "maxLength": 200, "description": "Shown on \"Thank You\" page" } }, "required": [ "status", "schema", "show_branding", "redirect_url", "success_title", "success_message" ] }, "FormSchemaV1": { "$id": "#/components/schemas/FormSchemaV1", "type": "object", "properties": { "schema_version": { "type": "number", "enum": [ 1 ] }, "fields": { "minItems": 1, "maxItems": 200, "type": "array", "items": { "oneOf": [ { "$ref": "#/components/schemas/StringFieldV1" }, { "$ref": "#/components/schemas/StringArrayFieldV1" }, { "$ref": "#/components/schemas/NumberFieldV1" }, { "$ref": "#/components/schemas/NumberArrayFieldV1" }, { "$ref": "#/components/schemas/BooleanFieldV1" }, { "$ref": "#/components/schemas/DateFieldV1" }, { "$ref": "#/components/schemas/SelectFieldV1" }, { "$ref": "#/components/schemas/SelectArrayFieldV1" }, { "$ref": "#/components/schemas/FileFieldV1" }, { "$ref": "#/components/schemas/FileArrayFieldV1" }, { "$ref": "#/components/schemas/HeadingFieldV1" }, { "$ref": "#/components/schemas/ParagraphFieldV1" }, { "$ref": "#/components/schemas/SeparatorFieldV1" } ] } } }, "required": [ "schema_version", "fields" ], "additionalProperties": false }, "FormAnalytics": { "type": "object", "properties": { "date": { "type": "string", "description": "Format: YYYY-MM-DD" }, "hours": { "type": "object", "properties": {}, "required": [], "description": "Key: String representing an hour between \"0\" and \"23\".\n\nValue: Number of submissions during that hour.\n\nNote: Some keys may be absent if there were no submissions during that hour.\nNote: Both `date` and `hours` are in UTC timezone.", "additionalProperties": { "type": "number" } }, "countries": { "type": "object", "properties": {}, "required": [], "description": "Key: Two-character ISO 3166-1 alpha-2 country code, or an empty string if the country couldn't be determined.\n\nValue: Value: Number of submissions from the corresponding country.", "additionalProperties": { "type": "number" } }, "user_agents": { "type": "object", "properties": {}, "required": [], "description": "Key: Parsed user agent string representing the browser and operating system from which the form was submitted.\n\nValue: Number of submissions associated with that user-agent.\n\nNote: Each key is a parsed user agent string containing information in the format \"browser - operating system\".\nNote: If either the browser or the operating system couldn't be recognized, the value for that part will be \"Unknown\".", "additionalProperties": { "type": "number" } }, "referers": { "type": "object", "properties": {}, "required": [], "description": "Key: URL of the page where the form was submitted from, or an empty string if the referer header was not sent.\n\nValue: Number of submissions from that referer.", "additionalProperties": { "type": "number" } } }, "required": [ "date", "hours", "countries", "user_agents", "referers" ] }, "ApiError": { "type": "object", "properties": { "message": { "type": "string" } }, "required": [ "message" ], "description": "Generic error (e.g. invalid auth)." }, "ApiValidationError": { "type": "object", "properties": { "errors": { "type": "array", "items": { "type": "object", "properties": { "path": { "type": "string" }, "expected": { "type": "string" } }, "required": [ "path", "expected" ] } }, "message": { "type": "string" } }, "required": [ "errors", "message" ], "description": "Input validation failed." }, "PaginatedSubmission": { "type": "object", "properties": { "results": { "type": "array", "items": { "$ref": "#/components/schemas/Submission" } }, "total": { "type": "number", "description": "Total number of results." } }, "required": [ "results", "total" ] }, "Submission": { "type": "object", "properties": { "id": { "type": "string" }, "country": { "type": "string", "description": "Two-character ISO 3166-1 alpha-2 country code, or an empty string if the country couldn't be determined." }, "ip": { "type": "string" }, "user_agent": { "type": "string", "description": "User agent string representing the browser or device from which the form was submitted, or an empty string if the user-agent header was not sent." }, "referer": { "type": "string", "description": "URL of the page where the form was submitted from, or an empty string if the referer header was not sent." }, "data": { "type": "object", "additionalProperties": true, "description": "Submitted JSON data.", "examples": [ { "name": "John Doe", "email": "test@vexrun.com", "message": "Hello!", "age": 30, "rating": 4.5, "subscribed": true, "address": { "city": "Warsaw", "country": "Poland" }, "tags": [ "support", "billing" ], "languages": [ { "code": "pl", "level": "native" }, { "code": "en", "level": "fluent" }, { "code": "de", "level": "beginner" } ] } ] }, "files": { "type": "array", "items": { "$ref": "#/components/schemas/SubmissionFile" } }, "created_at": { "type": "number", "description": "Measured in milliseconds since the Unix epoch." } }, "required": [ "id", "country", "ip", "user_agent", "referer", "data", "files", "created_at" ] }, "SubmissionFile": { "type": "object", "properties": { "id": { "type": "string" }, "field_name": { "type": "string", "description": "Name attribute of the input the file was attached to.\nOriginal file names aren't saved for security reasons." }, "size": { "type": "number", "description": "File size in bytes." }, "mime_type": { "type": "string" }, "ext": { "type": "string", "description": "File extension, including the dot or an empty string." } }, "required": [ "id", "field_name", "size", "mime_type", "ext" ] }, "Usage": { "type": "object", "properties": { "forms": { "type": "object", "properties": { "current": { "type": "number", "description": "Current number of forms." }, "max": { "type": "number", "description": "Maximum number of forms allowed in the current plan." } }, "required": [ "current", "max" ] }, "submissions": { "type": "object", "properties": { "current": { "type": "number", "description": "Current number of submissions." }, "max": { "type": "number", "description": "Maximum number of submissions allowed in the current plan." } }, "required": [ "current", "max" ] }, "file_storage": { "type": "object", "properties": { "current": { "type": "number", "description": "Currently used file storage in bytes." }, "max": { "type": "number", "description": "Maximum allowed file storage in bytes for the current plan." } }, "required": [ "current", "max" ] } }, "required": [ "forms", "submissions", "file_storage" ] }, "StringFieldV1": { "$id": "#/components/schemas/StringFieldV1", "type": "object", "properties": { "type": { "type": "string", "enum": [ "string" ] }, "name": { "type": "string", "minLength": 1, "maxLength": 100, "pattern": "^[a-zA-Z0-9_-]+$" }, "label": { "type": "string", "minLength": 1, "maxLength": 300 }, "hint": { "nullable": true, "type": "string", "minLength": 1, "maxLength": 300 }, "placeholder": { "nullable": true, "type": "string", "minLength": 1, "maxLength": 300 }, "validation": { "type": "object", "properties": { "required": { "type": "boolean" }, "type": { "type": "string", "enum": [ "text", "textarea", "email", "url" ] }, "min_length": { "nullable": true, "type": "integer", "minimum": 1, "maximum": 100000 }, "max_length": { "nullable": true, "type": "integer", "minimum": 1, "maximum": 100000 } }, "required": [ "required", "type", "min_length", "max_length" ], "additionalProperties": false } }, "required": [ "type", "name", "label", "hint", "placeholder", "validation" ], "additionalProperties": false }, "StringArrayFieldV1": { "$id": "#/components/schemas/StringArrayFieldV1", "type": "object", "properties": { "type": { "type": "string", "enum": [ "string_array" ] }, "name": { "type": "string", "minLength": 1, "maxLength": 100, "pattern": "^[a-zA-Z0-9_-]+$" }, "label": { "type": "string", "minLength": 1, "maxLength": 300 }, "hint": { "nullable": true, "type": "string", "minLength": 1, "maxLength": 300 }, "placeholder": { "nullable": true, "type": "string", "minLength": 1, "maxLength": 300 }, "validation": { "type": "object", "properties": { "min_length": { "nullable": true, "type": "integer", "minimum": 1, "maximum": 1000 }, "max_length": { "nullable": true, "type": "integer", "minimum": 1, "maximum": 1000 } }, "required": [ "min_length", "max_length" ], "additionalProperties": false }, "element_validation": { "type": "object", "properties": { "type": { "type": "string", "enum": [ "text", "textarea", "email", "url" ] }, "min_length": { "nullable": true, "type": "integer", "minimum": 1, "maximum": 100000 }, "max_length": { "nullable": true, "type": "integer", "minimum": 1, "maximum": 100000 } }, "required": [ "type", "min_length", "max_length" ], "additionalProperties": false } }, "required": [ "type", "name", "label", "hint", "placeholder", "validation", "element_validation" ], "additionalProperties": false }, "NumberFieldV1": { "$id": "#/components/schemas/NumberFieldV1", "type": "object", "properties": { "type": { "type": "string", "enum": [ "number" ] }, "name": { "type": "string", "minLength": 1, "maxLength": 100, "pattern": "^[a-zA-Z0-9_-]+$" }, "label": { "type": "string", "minLength": 1, "maxLength": 300 }, "hint": { "nullable": true, "type": "string", "minLength": 1, "maxLength": 300 }, "placeholder": { "nullable": true, "type": "string", "minLength": 1, "maxLength": 300 }, "validation": { "type": "object", "properties": { "required": { "type": "boolean" }, "min": { "nullable": true, "type": "number" }, "max": { "nullable": true, "type": "number" }, "step": { "nullable": true, "type": "number", "minimum": 0.0001 } }, "required": [ "required", "min", "max", "step" ], "additionalProperties": false } }, "required": [ "type", "name", "label", "hint", "placeholder", "validation" ], "additionalProperties": false }, "NumberArrayFieldV1": { "$id": "#/components/schemas/NumberArrayFieldV1", "type": "object", "properties": { "type": { "type": "string", "enum": [ "number_array" ] }, "name": { "type": "string", "minLength": 1, "maxLength": 100, "pattern": "^[a-zA-Z0-9_-]+$" }, "label": { "type": "string", "minLength": 1, "maxLength": 300 }, "hint": { "nullable": true, "type": "string", "minLength": 1, "maxLength": 300 }, "placeholder": { "nullable": true, "type": "string", "minLength": 1, "maxLength": 300 }, "validation": { "type": "object", "properties": { "min_length": { "nullable": true, "type": "integer", "minimum": 1, "maximum": 1000 }, "max_length": { "nullable": true, "type": "integer", "minimum": 1, "maximum": 1000 } }, "required": [ "min_length", "max_length" ], "additionalProperties": false }, "element_validation": { "type": "object", "properties": { "min": { "nullable": true, "type": "number" }, "max": { "nullable": true, "type": "number" }, "step": { "nullable": true, "type": "number", "minimum": 0.0001 } }, "required": [ "min", "max", "step" ], "additionalProperties": false } }, "required": [ "type", "name", "label", "hint", "placeholder", "validation", "element_validation" ], "additionalProperties": false }, "BooleanFieldV1": { "$id": "#/components/schemas/BooleanFieldV1", "type": "object", "properties": { "type": { "type": "string", "enum": [ "boolean" ] }, "name": { "type": "string", "minLength": 1, "maxLength": 100, "pattern": "^[a-zA-Z0-9_-]+$" }, "label": { "type": "string", "minLength": 1, "maxLength": 300 }, "hint": { "nullable": true, "type": "string", "minLength": 1, "maxLength": 300 }, "validation": { "type": "object", "properties": { "required": { "type": "boolean" }, "is_mandatory": { "type": "boolean", "description": "Specifies whether the field must be set to `true` if provided.\n\n- **When `required` is `true`:**\n - If `is_mandatory: true`: The field must be filled with `true`.\n - If `is_mandatory: false`: The field can be filled with either `true` or `false`.\n\n- **When `required` is `false`:**\n - If `is_mandatory: true`: The field can be `null` or must be `true` if provided.\n - If `is_mandatory: false`: The field can be `null` or filled with either `true` or `false`." } }, "required": [ "required", "is_mandatory" ], "additionalProperties": false } }, "required": [ "type", "name", "label", "hint", "validation" ], "additionalProperties": false }, "DateFieldV1": { "$id": "#/components/schemas/DateFieldV1", "type": "object", "properties": { "type": { "type": "string", "enum": [ "date" ] }, "name": { "type": "string", "minLength": 1, "maxLength": 100, "pattern": "^[a-zA-Z0-9_-]+$" }, "label": { "type": "string", "minLength": 1, "maxLength": 300 }, "hint": { "nullable": true, "type": "string", "minLength": 1, "maxLength": 300 }, "placeholder": { "nullable": true, "type": "string", "minLength": 1, "maxLength": 300 }, "validation": { "type": "object", "properties": { "required": { "type": "boolean" }, "min_date": { "nullable": true, "type": "string", "format": "date", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$" }, "max_date": { "nullable": true, "type": "string", "format": "date", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$" } }, "required": [ "required", "min_date", "max_date" ], "additionalProperties": false } }, "required": [ "type", "name", "label", "hint", "placeholder", "validation" ], "additionalProperties": false }, "SelectFieldV1": { "$id": "#/components/schemas/SelectFieldV1", "type": "object", "properties": { "type": { "type": "string", "enum": [ "select" ] }, "name": { "type": "string", "minLength": 1, "maxLength": 100, "pattern": "^[a-zA-Z0-9_-]+$" }, "label": { "type": "string", "minLength": 1, "maxLength": 300 }, "hint": { "nullable": true, "type": "string", "minLength": 1, "maxLength": 300 }, "placeholder": { "nullable": true, "type": "string", "minLength": 1, "maxLength": 300 }, "options": { "minItems": 1, "maxItems": 1000, "type": "array", "items": { "type": "object", "properties": { "value": { "type": "string", "minLength": 1, "maxLength": 500 }, "label": { "type": "string", "minLength": 1, "maxLength": 500 } }, "required": [ "value", "label" ], "additionalProperties": false } }, "validation": { "type": "object", "properties": { "required": { "type": "boolean" } }, "required": [ "required" ], "additionalProperties": false } }, "required": [ "type", "name", "label", "hint", "placeholder", "options", "validation" ], "additionalProperties": false }, "SelectArrayFieldV1": { "$id": "#/components/schemas/SelectArrayFieldV1", "type": "object", "properties": { "type": { "type": "string", "enum": [ "select_array" ] }, "name": { "type": "string", "minLength": 1, "maxLength": 100, "pattern": "^[a-zA-Z0-9_-]+$" }, "label": { "type": "string", "minLength": 1, "maxLength": 300 }, "hint": { "nullable": true, "type": "string", "minLength": 1, "maxLength": 300 }, "placeholder": { "nullable": true, "type": "string", "minLength": 1, "maxLength": 300 }, "options": { "minItems": 1, "maxItems": 1000, "type": "array", "items": { "type": "object", "properties": { "value": { "type": "string", "minLength": 1, "maxLength": 500 }, "label": { "type": "string", "minLength": 1, "maxLength": 500 } }, "required": [ "value", "label" ], "additionalProperties": false } }, "validation": { "type": "object", "properties": { "min_length": { "nullable": true, "type": "integer", "minimum": 1, "maximum": 1000 }, "max_length": { "nullable": true, "type": "integer", "minimum": 1, "maximum": 1000 } }, "required": [ "min_length", "max_length" ], "additionalProperties": false } }, "required": [ "type", "name", "label", "hint", "placeholder", "options", "validation" ], "additionalProperties": false }, "FileFieldV1": { "$id": "#/components/schemas/FileFieldV1", "type": "object", "properties": { "type": { "type": "string", "enum": [ "file" ] }, "name": { "type": "string", "minLength": 1, "maxLength": 100, "pattern": "^[a-zA-Z0-9_-]+$" }, "label": { "type": "string", "minLength": 1, "maxLength": 300 }, "hint": { "nullable": true, "type": "string", "minLength": 1, "maxLength": 300 }, "placeholder": { "nullable": true, "type": "string", "minLength": 1, "maxLength": 300 }, "validation": { "type": "object", "properties": { "required": { "type": "boolean" }, "acceptable_file_types": { "nullable": true, "description": "https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/accept", "minItems": 1, "maxItems": 15, "type": "array", "items": { "type": "string", "minLength": 1, "maxLength": 100 } }, "min_size": { "nullable": true, "type": "integer", "minimum": 1, "maximum": 100000000 }, "max_size": { "nullable": true, "type": "integer", "minimum": 1, "maximum": 100000000 } }, "required": [ "required", "acceptable_file_types", "min_size", "max_size" ], "additionalProperties": false } }, "required": [ "type", "name", "label", "hint", "placeholder", "validation" ], "additionalProperties": false }, "FileArrayFieldV1": { "$id": "#/components/schemas/FileArrayFieldV1", "type": "object", "properties": { "type": { "type": "string", "enum": [ "file_array" ] }, "name": { "type": "string", "minLength": 1, "maxLength": 100, "pattern": "^[a-zA-Z0-9_-]+$" }, "label": { "type": "string", "minLength": 1, "maxLength": 300 }, "hint": { "nullable": true, "type": "string", "minLength": 1, "maxLength": 300 }, "placeholder": { "nullable": true, "type": "string", "minLength": 1, "maxLength": 300 }, "validation": { "type": "object", "properties": { "min_length": { "nullable": true, "type": "integer", "minimum": 1, "maximum": 1000 }, "max_length": { "nullable": true, "type": "integer", "minimum": 1, "maximum": 1000 } }, "required": [ "min_length", "max_length" ], "additionalProperties": false }, "element_validation": { "type": "object", "properties": { "acceptable_file_types": { "nullable": true, "description": "https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/accept", "minItems": 1, "maxItems": 15, "type": "array", "items": { "type": "string", "minLength": 1, "maxLength": 100 } }, "min_size": { "nullable": true, "type": "integer", "minimum": 1, "maximum": 100000000 }, "max_size": { "nullable": true, "type": "integer", "minimum": 1, "maximum": 100000000 } }, "required": [ "acceptable_file_types", "min_size", "max_size" ], "additionalProperties": false } }, "required": [ "type", "name", "label", "hint", "placeholder", "validation", "element_validation" ], "additionalProperties": false }, "HeadingFieldV1": { "$id": "#/components/schemas/HeadingFieldV1", "type": "object", "properties": { "type": { "type": "string", "enum": [ "heading" ] }, "level": { "type": "number", "enum": [ 1, 2, 3 ] }, "content": { "type": "string", "minLength": 0, "maxLength": 300 } }, "required": [ "type", "level", "content" ], "additionalProperties": false }, "ParagraphFieldV1": { "$id": "#/components/schemas/ParagraphFieldV1", "type": "object", "properties": { "type": { "type": "string", "enum": [ "paragraph" ] }, "content": { "type": "string", "minLength": 0, "maxLength": 1000 } }, "required": [ "type", "content" ], "additionalProperties": false }, "SeparatorFieldV1": { "$id": "#/components/schemas/SeparatorFieldV1", "type": "object", "properties": { "type": { "type": "string", "enum": [ "separator" ] } }, "required": [ "type" ], "additionalProperties": false } }, "securitySchemes": { "x-api-key": { "type": "apiKey", "name": "x-api-key", "in": "header" }, "x-team-id": { "type": "apiKey", "name": "x-team-id", "in": "header" } } }, "tags": [ { "name": "Forms" }, { "name": "Submissions" }, { "name": "Schema" }, { "name": "Analytics" }, { "name": "Files" }, { "name": "Usage" } ] } ```