# Formspark Documentation > Every page of https://documentation.formspark.io, in sidebar order. Source: https://documentation.formspark.io/index.md
# About Welcome to the documentation website for [Formspark](https://formspark.io?ref=documentation). Formspark is a simple way to save information from your website via forms without having to set up a server. Formspark is perfect for static sites and works anywhere you can put an HTML form. ## What it's good for Contact forms, newsletter signups, lead capture, surveys, feedback widgets, RSVPs, waitlists, and any HTML form that needs a place to send its data. ## What it isn't Formspark is not a drag-and-drop form builder. You bring your own HTML; Formspark stores submissions, sends notifications, and forwards data to your tools. Don't have an account yet? [Sign up for free!](https://dashboard.formspark.io). --- Source: https://documentation.formspark.io/setup/index.md # Installation ## Getting your form ID Every form in Formspark has its own action URL. To get one, sign in to the [Formspark dashboard](https://dashboard.formspark.io) and create a new form. The form opens on its `How-to` tab, which shows the action URL in a setup guide for your stack. The URL ends with your form's unique ID. ## HTML ```html
``` **1.** Set your HTML form's `action` attribute to your form's action URL. Your form's unique action URL looks something like this: `https://submit-form.com/your-form-id`. **2.** Ensure all input, select and textarea elements inside your form have a `name` attribute, otherwise you will not receive the data filled in these fields. Input names starting with an underscore are reserved for control fields such as `_redirect`. Formspark does not store them with the submission, so they never appear in the dashboard or in notification emails. **3.** Verify that your form contains a button element with the "submit" `type`. ## Testing You can rapidly test your form payloads by submitting to https://submit-form.com/echo. ```html
``` ![Echo](https://documentation.formspark.io/submit-echo.png) ## JavaScript Formspark has excellent AJAX support, [learn more about it here](https://documentation.formspark.io/examples/ajax.md). --- Source: https://documentation.formspark.io/setup/spam-protection.md # Spam protection Every form falls victim to spambots at some point, and how you handle them can affect your customers. Formspark offers the following solutions to prevent spam: - [Botpoison](https://botpoison.com/) integration - [reCAPTCHA](https://www.google.com/recaptcha/about/) integration - [hCaptcha](https://www.hcaptcha.com/) integration - [Turnstile](https://www.cloudflare.com/products/turnstile/) integration - Custom spam words - Allowed domains - Honeypot technique On top of whichever of these you enable, every submission is screened by our [automatic spam filtering](#automatic-spam-filtering), unless you switch it off for that form. ![Spam protection](https://documentation.formspark.io/spam-protection.png) Formspark will not deliver a submission to your inbox, send notifications or decrement your submission counter if any of the following conditions are true: - The submission is empty - The challenge verification was unsuccessful - The submission contains a honeypot - The submission contains one of your custom spam words - The submission was sent from a site that is not on your allowed domains - The automatic filter flags the submission as spam An empty submission is discarded. Every other rejected submission is kept for you to review. See [rejected submissions](#rejected-submissions). ## Rejected submissions A submission rejected as spam lands under `Spam` instead of `Inbox`. Open your form's `Submissions` and switch the view to `Spam` to see it. Hover its `Spam` tag to see what rejected it. Rejected submissions stay there for up to 30 days. To recover one, use `Mark as non-spam`: it moves to your inbox and counts against your submission quota. Your visitor sees an error for a rejected submission. A plain HTML form shows the error page, or your error redirect if you set one. An AJAX request answers `403` with `Rejected by spam protection`. ## Which should I pick? | Provider | Visitor experience | Pricing | Strength | | ----------------------------------------------------------- | ------------------ | ----------- | -------- | | [Botpoison](https://botpoison.com/) | Invisible | Free / paid | Strong | | [Turnstile](https://www.cloudflare.com/products/turnstile/) | Invisible | Free | Strong | | [hCaptcha](https://www.hcaptcha.com/) | Checkbox | Free | Strong | | [reCAPTCHA](https://www.google.com/recaptcha/about/) | Checkbox | Free | Strong | | Custom spam words | Invisible | Included | Low | | Allowed domains | Invisible | Included | Low | | Honeypot | Invisible | Included | Low | If you're not sure, start with **Botpoison** or **Turnstile**: both are invisible to your visitors and require no interaction. ## Botpoison Formspark integrates with Botpoison, an invisible, user-friendly anti-spam solution. ### Getting started 1. Go to [https://botpoison.com/start/](https://botpoison.com/start/). 2. Create a new configuration. 3. Integrate the `public key` on your website ([instructions](https://botpoison.com/documentation/getting-started/html/)). 4. Copy the `secret key`. 5. Open Formspark. 6. In your form's settings, under `Spam protection`, open `Challenge` and select `Botpoison` as the `Provider`. 7. Paste the `secret key` into the `Botpoison secret key` field. Your form is now protected by Botpoison ✔. To stop using Botpoison, set the `Provider` under `Challenge` back to `None`. ### Example ```html
``` ### AJAX If you're using AJAX, add the Botpoison response to your submission body via the `_botpoison` property. ```javascript const body = { email: "john.doe@example.com", message: "Hello, World!", _botpoison: "...", }; ``` ### Recommended libraries - JavaScript: [@botpoison/browser](https://www.npmjs.com/package/@botpoison/browser) ## reCAPTCHA Formspark integrates with Google's reCAPTCHA v2 "I'm not a robot" checkbox. ### Getting started 1. Go to [https://www.google.com/recaptcha/](https://www.google.com/recaptcha/). 2. Navigate to the admin console. 3. Create a new site. 4. Make sure you select `reCAPTCHA v2`. 5. Make sure you whitelist your website's domain. 6. Integrate the `site key` on your website ([instructions](https://developers.google.com/recaptcha/docs/display)). 7. Copy the `secret` key. 8. Open Formspark. 9. In your form's settings, under `Spam protection`, open `Challenge` and select `reCAPTCHA v2` as the `Provider`. 10. Paste the `secret key` into the `reCAPTCHA v2 secret key` field. Your form is now protected by reCAPTCHA ✔. To stop using reCAPTCHA, set the `Provider` under `Challenge` back to `None`. ### HTML Make sure your form's `method` attribute is explicitly set to `POST`. ```html
...
``` ### AJAX If you're using AJAX, add the reCAPTCHA response to your submission body via the `g-recaptcha-response` property. ```javascript const body = { email: "john.doe@example.com", message: "Hello, World!", "g-recaptcha-response": "...", }; ``` ### Recommended libraries - React: [react-google-recaptcha](https://github.com/dozoisch/react-google-recaptcha) ### Articles - [How to enable your submit button based on reCAPTCHA results](https://technotrampoline.com/articles/how-to-enable-your-submit-button-based-on-recaptcha-results/) ## hCaptcha Formspark integrates with hCaptcha, an independent alternative to Google's reCAPTCHA. ### Getting started 1. Go to [https://www.hcaptcha.com/](https://www.hcaptcha.com/). 2. Create a new site. 3. Integrate the `site key` on your website ([instructions](https://docs.hcaptcha.com/#add-the-hcaptcha-widget-to-your-webpage)). You can find your site key [here](https://dashboard.hcaptcha.com/sites). 4. Copy the `secret key`. You can find your secret key [here](https://dashboard.hcaptcha.com/settings). 5. In your form's settings, under `Spam protection`, open `Challenge` and select `hCaptcha` as the `Provider`. 6. Paste the `secret key` into the `hCaptcha secret key` field. Your form is now protected by hCaptcha ✔. To stop using hCaptcha, set the `Provider` under `Challenge` back to `None`. ### HTML Make sure your form's `method` attribute is explicitly set to `POST`. ```html
...
``` ### AJAX If you're using AJAX, add the hCaptcha response to your submission body via the `h-captcha-response` property. ```javascript const body = { email: "john.doe@example.com", message: "Hello, World!", "h-captcha-response": "...", }; ``` ### Recommended libraries - React: [react-hcaptcha](https://github.com/hCaptcha/react-hcaptcha) ## Turnstile Formspark integrates with Turnstile, Cloudflare's smart CAPTCHA alternative. ### Getting started 1. Go to [https://www.cloudflare.com/products/turnstile](https://www.cloudflare.com/products/turnstile/). 2. Create a new site. 3. Integrate the `site key` on your website ([instructions](https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/)). 4. Copy the `secret key`. 5. In your form's settings, under `Spam protection`, open `Challenge` and select `Turnstile` as the `Provider`. 6. Paste the `secret key` into the `Turnstile secret key` field. Your form is now protected by Turnstile ✔. To stop using Turnstile, set the `Provider` under `Challenge` back to `None`. ### AJAX If you're using AJAX, add the Turnstile response to your submission body via the `cf-turnstile-response` property. ```javascript const body = { email: "john.doe@example.com", message: "Hello, World!", "cf-turnstile-response": "...", }; ``` ### Recommended libraries - React: [react-turnstile](https://github.com/Le0Developer/react-turnstile) ## Automatic spam filtering On top of any provider you choose, Formspark screens every submission for spam. It is on for every new form, requires no setup, and is invisible to your visitors. The filtering is powered by Botpoison Classify, and you do not need a Botpoison account for it. It complements the challenge you select above rather than replacing it. ### Switching it off Under `Spam protection` in your form's settings, open `Automatic filter` and turn off `Screen submissions for spam`. Two things change for that form when you do: - Every submission is delivered, including the ones the filter would have held back. Each of those counts against your submission quota, where a filtered submission costs you nothing. - Filtered submissions no longer appear under `Spam`, which is where you would otherwise recover one the filter judged wrongly. Your honeypot, custom spam words and chosen provider are unaffected and keep running. ## Custom spam words Custom spam words let you block submissions that contain specific words. We scan the fields your visitor filled in for the words you specify. Matching ignores case and also finds a word inside a longer one. If a word is found, the submission is rejected as spam. Fields your visitor did not write are skipped: control fields such as `_redirect`, challenge responses such as `g-recaptcha-response`, and tracking fields such as UTM tags (`utm_source`) and ad click ids (`gclid`, `fbclid`). You specify the comma-separated list of words in your form's settings, under `Spam protection` in `Spam words`. The total length of the list must not exceed 2,560 characters. ## Allowed domains List the sites your form lives on, and submissions sent from anywhere else are rejected as spam. Set it in your form's settings, under `Spam protection` in `Allowed domains`. It is off until you add a domain. - Each domain also covers its subdomains: `example.com` allows `www.example.com` and `shop.example.com`. - You can paste a full address. `https://www.example.com/contact` is saved as `example.com`. - Submissions sent from a server, or by a tool such as `curl`, are rejected, because they do not say which site they come from. - To test on your own machine, add `localhost` to the list. ## Honeypot ::: warning While simple to implement, this technique is not the most effective. Modern spam bots that execute JavaScript can detect hidden fields and skip them, bypassing the honeypot entirely. Pair it with another provider above for serious protection. ::: The honeypot technique is a simple-to-implement spam prevention solution. To enable this feature, add a field with the name `_honeypot` or `_gotcha` to your form and hide it with CSS (see example below). When a spam bot enters a value, the submission is rejected as spam. ```html
``` ## Custom honeypot Besides `_honeypot` and `_gotcha`, you can specify your own honeypot name in your form's settings, under `Spam protection` in `Honeypot`. Enter it in the `Custom field name` field. The name must match your field's `name` exactly, including case. ```html
``` --- Source: https://documentation.formspark.io/setup/file-uploads.md # File uploads ::: tip Formspark stores a link to your uploaded file, not the file itself. You upload the file to a third-party storage provider and Formspark records the resulting URL with the submission. A submission that carries the file itself is rejected with a `400` error. ::: The examples below use Uploadcare and Cloudinary. Any provider that returns a public URL after upload will work the same way. ## Uploadcare Create an Uploadcare account at [https://uploadcare.com/](https://uploadcare.com/). ::: warning Uploadcare's free plan is metered in operations, not uploads, and an operation covers uploading, image transformations, video processing and document conversion alike. The allowance is small enough that a busy form will pass it, and the cheapest paid plan is a significant step up. Check [their pricing](https://uploadcare.com/pricing/) against your expected volume before you commit, and see [Cloudinary](#cloudinary) below for another option. ::: ### Steps Start with a simple Formspark form. ```html
``` Add the Uploadcare widget to the `head` of your HTML file. ```html ``` Add an input of type `hidden`, set its role to `uploadcare-uploader`, add your Uploadcare public key as the `data-public-key` attribute. ```html ``` Links to the uploaded files will now automatically be attached to your submissions. ![Uploadcare submission](https://documentation.formspark.io/uploadcare-submission.png) Final code: ```html Formspark with Uploadcare
``` ## Cloudinary [Cloudinary](https://cloudinary.com/) offers an upload widget that works the same way: the visitor uploads, and you put the resulting URL into a hidden field that Formspark records. ### Steps Create an [unsigned upload preset](https://cloudinary.com/documentation/upload_presets) in your Cloudinary console. Unsigned is what lets the browser upload without a server-side signature, so the preset should restrict what it accepts. Add the widget script to the `head` of your HTML file. ```html ``` Add a hidden input to hold the URL, and a button that opens the widget. ```html ``` Wire the widget up so a successful upload writes its URL into that input. ```html ``` The submitted `photo` field now carries the uploaded file's URL. ::: tip Give the button `type="button"`. A button inside a form defaults to `type="submit"`, so without it opening the widget submits the form instead. ::: ## Alternatives - [Filestack](https://www.filestack.com/): drop-in widget similar to Uploadcare. - [Bunny Storage](https://bunny.net/storage/): cheap edge storage with a simple HTTP API. - [Amazon S3 pre-signed URLs](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-presigned-url.html): generate an upload URL from your own backend, then submit the resulting file URL to Formspark. --- Source: https://documentation.formspark.io/setup/arrays-and-objects.md # Working with arrays and objects ## Arrays > An array is a collection of similar data elements. ### HTML You can submit an array by using the `name[index]` syntax: ```html
``` ### AJAX ```javascript axios.post("https://submit-form.com/your-form-id", { ingredients: ["anchovies", "cheese", "flour", "tomato", "water"], }); ``` ## Objects > An object is a standalone entity with properties. ### HTML You can submit an object by using the `name.property` syntax: ```html
``` To submit an array of objects: ```html
``` ### AJAX To submit an object: ```javascript axios.post("https://submit-form.com/your-form-id", { car: { manufacturer: "Ferrari", color: "Red", }, }); ``` To submit an array of objects: ```javascript axios.post("https://submit-form.com/your-form-id", { cars: [ { manufacturer: "Ferrari", color: "Red", }, ], }); ``` --- Source: https://documentation.formspark.io/customization/redirection.md # Redirection After submitting a form, the user will be redirected to a generic [feedback page](https://documentation.formspark.io/customization/feedback-page.md) hosted by Formspark. This default behavior can be overridden in multiple ways. ## Specifying a custom redirect URL 1. Add an input of type `hidden`. 2. Set the input's name to `_redirect`. 3. Set the value to the URL you want to redirect users to. ```html
``` The value can also be a path, such as `/thanks`. Formspark resolves it against the page the form was submitted from, the way a link on that page would. Only `http` and `https` addresses are followed; anything else sends the visitor to the default feedback page. By default, Formspark appends the submission's entries to the custom redirect URL (to its search string). This enables you to personalize your page with user-submitted data. The above form's submissions would redirect to `https://your-website.com/thanks?email=example%40email.com`. You can toggle off this behavior by adding a hidden input with the name `_append` and the value `false`. ```html ``` ## Specifying a custom error redirect URL Note: If you don't specify a custom error redirect URL then the configuration from `_redirect` (if present) will automatically be inherited. 1. Add an input of type `hidden`. 2. Set the input's name to `_error`. 3. Set the value to the URL you want to redirect users to. ```html
``` ::: tip `_redirect` is only used for full-page form submissions. When you submit via AJAX with `Accept: application/json`, Formspark returns a JSON response instead and `_redirect` is silently ignored. Handle the post-submission UX yourself in JavaScript. ::: ## Preventing the redirect ### Staying on the same page (without leaving it) This is only possible with JavaScript/AJAX. Formspark has excellent AJAX support, [learn more about it here](https://documentation.formspark.io/examples/ajax.md). ### Returning to the same page (after leaving it) ```html
``` This method is based on illusion. Technically, you are not preventing the redirection. --- Source: https://documentation.formspark.io/customization/feedback-page.md # Feedback page After submitting a form, the user will be [redirected](https://documentation.formspark.io/customization/redirection.md) to a generic feedback page hosted by Formspark. ![Feedback OK](https://documentation.formspark.io/feedback-ok.png) You can customize the look-and-feel and content of the default feedback page with the following reserved input names. ### `_feedback.whitelabel` Removes all Formspark branding from the feedback page. You need an [upgraded workspace](https://documentation.formspark.io/troubleshooting/limits-and-plans.md) to unlock this feature; on a free workspace the flag is ignored. Default value: false ```html
``` ### `_feedback.dark` Toggles dark mode. Default value: false ```html
``` ![Feedback dark mode](https://documentation.formspark.io/feedback-dark-mode.png) ### `_feedback.language` Customizes the language of the feedback page. Default value: the value of [`_language`](https://documentation.formspark.io/customization/language.md) when set, otherwise "en" See [Language](https://documentation.formspark.io/customization/language.md#supported-values) for the supported values. Prefer `_language`, which also translates the autoresponder. ### `_feedback.success.title` Customizes the title of the success feedback page. Default value: "Your form has been submitted." ### `_feedback.success.message` Customizes the message of the success feedback page. Default value: _none_ ### `_feedback.error.title` Customizes the title of the error feedback page. Default value: "An error has occurred." ### `_feedback.error.message` Customizes the message of the error feedback page. Default value: "Please try again." ### Example ```html
``` ![Feedback OK custom title](https://documentation.formspark.io/feedback-ok-custom-title.png) --- Source: https://documentation.formspark.io/customization/language.md # Language Formspark writes a few things to your visitors itself: the feedback page they see after submitting, and the default subject and the footer of the [autoresponder](https://documentation.formspark.io/dashboard/autoresponder.md). By default these are in English. Add a hidden `_language` field to show them in your visitor's language: ```html
``` A multilingual site can set the value per page, so each visitor gets their own language. ## What `_language` translates | Where | What | | --------------------------------------------- | ------------------------------------------------------------- | | [Feedback page](https://documentation.formspark.io/customization/feedback-page.md) | The default title and message | | [Autoresponder](https://documentation.formspark.io/dashboard/autoresponder.md) | The default subject, and the footer with its unsubscribe link | It does not translate: - Text you write yourself, such as a custom feedback title or the body of your autoresponder template. Write those in the language you want. - Your own [notification emails](https://documentation.formspark.io/customization/notification-email.md). Those are for you, not your visitors. ## Supported values | Value | Language | | ----- | ------------------ | | "de" | German | | "en" | English | | "es" | Spanish | | "fr" | French | | "it" | Italian | | "ja" | Japanese | | "ko" | Korean | | "nl" | Dutch | | "pl" | Polish | | "pt" | Portuguese | | "ru" | Russian | | "uk" | Ukrainian | | "zh" | Simplified Chinese | Any other value falls back to English. ## The feedback page only `_feedback.language` sets the language of the feedback page alone. When a form sends both fields, the feedback page follows `_feedback.language` and the autoresponder follows `_language`. --- Source: https://documentation.formspark.io/customization/notification-email.md # Notification email ## Subject You can change the subject of the notification email. Create a hidden input with the name `_email.subject`. ```html ``` A [custom template](#custom-templates) can carry its own subject line instead. When the submission also has an `_email.subject` field, that field takes precedence. ## Sender name You can change the name of the sender of the notification email. Create a hidden input with the name `_email.from`. ```html ``` The value cannot contain `@`, `<` or `>`. A value that breaks this rule is ignored, and the email is sent as "Formspark Notifications". It is currently not possible to change the sender address. ## Template title You can change the title of the notification email template. Create a hidden input with the name `_email.template.title`. ```html ``` You can remove the title and the Formspark logo by setting the value to `false`. ```html ``` ## Dashboard button Team members get a "View submission" button that opens the submission in the dashboard. You can remove it. Create a hidden input with the name `_email.template.button` and the value `false`. ```html ``` Guests never get this button, since they cannot open the dashboard. ## Template footer You can remove the footer from the notification email template. Create a hidden input with the name `_email.template.footer` and the value `false`. ```html ``` Guests get no footer. Their mail client offers an unsubscribe button beside the sender instead. The title, button and footer options shape the default template. A [custom template](#custom-templates) is sent exactly as you designed it, with no footer for anyone. ## Custom templates You can go beyond these options and design the notification email in a visual template editor, built in partnership with [Postcraft](https://postcraft.io/). [Check this page](https://documentation.formspark.io/dashboard/email-notification-settings.md#custom-templates) to learn more about custom email templates. You can write the same template from your own code instead. See [templates](https://documentation.formspark.io/api/reference.md#templates) in the API reference. ## Autoresponder Notification emails go to you; the [autoresponder](https://documentation.formspark.io/dashboard/autoresponder.md) sends a confirmation email to the person who submitted your form. --- Source: https://documentation.formspark.io/customization/direct-replies.md # Direct replies From your email inbox, you can directly reply to the person who submitted the form. ![Direct replies](https://documentation.formspark.io/direct-replies.png) To activate this feature, create an input with any of the following names: - `mail` - `email` - `_replyto` - `_email.replyto` `mail` and `email` match in any case, so a field named `Email` works too. The underscore names must be spelled exactly as shown. ::: tip Use `type="email"` so the browser validates the address before submission. ::: ```html ``` ```html ``` ```html ``` ```html ``` ::: warning Input names starting with an underscore will be hidden from the dashboard and notification emails. ::: --- Source: https://documentation.formspark.io/customization/custom-routing.md # Custom routing You can use JavaScript to dynamically select a form endpoint. Using this technique, you can use a drop-down to dynamically route submissions to a specific team, department, inbox, webhook, etc. Each option points at a form of its own, so create one form per destination and swap in its action URL below. ```html
``` --- Source: https://documentation.formspark.io/dashboard/inviting-team-members.md # Inviting team members You can invite members to your workspace to create forms and view submissions as a team. Each member has a role that decides what they can change. When you invite team members to join your Formspark workspace, they will receive an invitation email. The link in it works once and expires after 7 days. Free workspaces include 5 team members. Upgraded workspaces hold up to 50. See [limits and plans](https://documentation.formspark.io/troubleshooting/limits-and-plans.md). :::tip You can send invitations to users who still need to create a Formspark account or to those who already have one. ::: ## Steps 1. Open the `Members` screen 2. Fill in their email 3. Choose their role 4. Press `Send invitation` ![Invite a member form](https://documentation.formspark.io/invite-team-member.png) ## Pending invitations Invitations nobody has accepted yet are listed under `Pending invitations` on the `Members` screen, with the number of days before each one expires. - Press `Resend` to email a fresh link. The old link stops working. - Press `Revoke` to take an invitation back. Its link stops working. An expired invitation stays in the list, so you can resend it. ## Roles Every member is an _admin_, an _editor_ or a _viewer_. | | Admin | Editor | Viewer | | ----------------------------------- | ----- | ------ | ------ | | Read submissions and analytics | Yes | Yes | Yes | | Export submissions | Yes | Yes | Yes | | Create and change forms | Yes | Yes | No | | Delete forms and submissions | Yes | Yes | No | | Connect and disconnect integrations | Yes | Yes | No | | Change spam protection | Yes | Yes | No | | Redeem a voucher | Yes | Yes | No | | Invite a member | Yes | Yes | No | | Resend or revoke an invitation | Yes | Yes | No | | Change a member's role | Yes | No | No | | Remove a member | Yes | No | No | | Leave the workspace | Yes | Yes | Yes | | See purchases and invoices | Yes | No | No | | Delete the workspace | Yes | No | No | A _viewer_ reads and nothing else. They cannot change a setting, break an integration or delete anything, so you can give a client access to their own submissions without giving them the rest of the workspace. An _editor_ builds and maintains forms. Only an _admin_ can invite another admin, or resend and revoke an admin invitation. A workspace always keeps at least one admin. An admin cannot be removed from the workspace. To remove one, change their role first. :::tip Choose the role when you send the invitation. You can change it later from the `Members` screen, next to the member's name. ::: ## Leaving a workspace 1. Open the `Members` screen 2. Press `Leave workspace` You lose access to its forms and submissions. To come back, someone in the workspace has to invite you again. The last admin cannot leave. Make another member an admin first, or delete the workspace instead. --- Source: https://documentation.formspark.io/dashboard/additional-workspaces.md # Additional workspaces A workspace is a group of forms and can have one or several team members. Workspaces enable you to create isolated environments for your customers, companies, departments, products, etc. Note that additional user-created workspaces start with 0 submissions. All upgrades, bundles, and deals are per workspace. See [limits and plans](https://documentation.formspark.io/troubleshooting/limits-and-plans.md). Each workspace lists its own [purchases and invoices](https://documentation.formspark.io/dashboard/purchases.md). ## Steps 1. Press the switch button to the right of your workspace's name 2. Press `Create workspace` 3. Fill in a name and press `Create` ![New workspace](https://documentation.formspark.io/new-workspace.png) ## Moving a form to another workspace Forms cannot be moved between workspaces from the dashboard. If you need to transfer a form, [contact support](mailto:support@formspark.io) and we'll move it for you. ## Deleting a workspace Only an admin can delete a workspace. See [roles](https://documentation.formspark.io/dashboard/inviting-team-members.md#roles). 1. Open the workspace's `Settings` screen 2. Under `Danger zone`, press `Delete` on the `Delete workspace` row 3. Type the workspace's name to confirm, then press `Delete workspace` Deletion cannot be undone, so export anything you want to keep first. See [exporting submissions](https://documentation.formspark.io/dashboard/exporting-submissions.md). - Its forms, submissions, notification settings and integrations are removed for everyone in it. Forms posting to it stop accepting submissions. - Its members lose access, and links in its pending invitations stop working. - Submissions bought for it are not refunded, since bundles belong to the workspace. You can delete a workspace that other people use, and your last workspace too. A workspace you create afterwards starts with 0 submissions. --- Source: https://documentation.formspark.io/dashboard/purchases.md # Purchases and invoices Workspace admins find every purchase, with its invoice, in the workspace's `Settings`, under `Billing` in `Purchases`. Press `View`, then `Invoice` next to the purchase. Older purchases offer a `Receipt` instead. To get a business invoice, add your company name, address and VAT number at checkout. If you missed it, press `Billing details` on the purchase, or add them on the receipt. --- Source: https://documentation.formspark.io/dashboard/redeeming-vouchers.md # Redeeming vouchers A voucher adds submissions to a workspace. Admins and editors can redeem one. ## Steps 1. Open the workspace's `Settings` screen 2. Under `Billing`, press `Redeem` on the `Voucher` row 3. Enter your voucher and press `Redeem` ![redeeming a voucher](https://documentation.formspark.io/redeem-voucher.png) --- Source: https://documentation.formspark.io/dashboard/email-notification-settings.md # Email notification settings To manage your form's email notification settings, open its `Settings` section and expand `Notifications` under `Emails`. ## Recipients - You can enable/disable email notifications for your workspace's team members. - You can add guests to send email notifications to people outside your workspace/organization. A guest receives a confirmation email first, and nothing else until they accept it. The recipient list shows a guest who has not accepted yet as pending. ![Email notification settings](https://documentation.formspark.io/email-notification-settings.png) ## Threading Email threading is on by default, so your mail client groups a form's notifications into one conversation. Turn it off to receive each submission as a separate email. ## Custom templates You can customize the notification email template of a form. Templates are designed in a visual editor, built in partnership with [Postcraft](https://postcraft.io/). A custom template goes out exactly as you designed it to every recipient, team member or guest. Formspark adds no footer and no unsubscribe link, so when a guest asks to stop receiving it, remove them from the recipients. Every custom template passes a content check. If the check pauses yours, the form sends no notifications and its settings say so. Contact support to have it reviewed, or press `Revert to default` to go back to the default template. Dynamic values in a template use the [Handlebars](https://handlebarsjs.com/) templating language. A template can also set the email's subject line, with the same dynamic values as the body. An `_email.subject` field in the submission takes precedence over it. ```handlebars
New submission:
First name: {{data.firstName}}
Last name: {{data.lastName}}
``` ### Custom Handlebars helpers The following custom Handlebars helpers have been registered for you: | Name | Description | Example usage | | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `capitalize` | Capitalizes the first character of a string and lowercases the rest. | `{{capitalize "hello world"}}` → `Hello world` | | `nl2br` | Converts newlines in a string into `
` HTML tags, so line breaks display correctly in HTML. | `{{nl2br user.comment}}` → `Line one
Line two` | | `pluralize` | Returns the singular or plural form of a word based on a count. Optionally accepts a custom plural form. | `{{pluralize 1 "item"}}` → `1 item`
`{{pluralize 3 "item"}}` → `3 items`
`{{pluralize 2 "child" "children"}}` → `2 children` | | `sanitizeUrl` | Returns the given URL only if it uses a safe scheme (`http(s)`, `mailto`, `tel`, a relative path, or an anchor); otherwise returns `#`. Use it around links built from submitted data so an unsafe value can't render a clickable exploit. | `{{sanitizeUrl viewLink}}` → `https://example.com` (or `#` if unsafe) | | `stringify` | Serializes a value to a JSON string. Supports optional indentation for pretty-printing. | `{{stringify data}}` → `{"name":"Alice","age":30}`
`{{stringify data indent=2}}` → pretty-printed JSON | | `switch` / `case` / `default` | Block helper for matching a value against multiple cases. Renders the content of the matching `case` block, or the `default` block if no case matches. | `{{#switch type}}{{#case "a"}}A{{/case}}{{#case "b"}}B{{/case}}{{#default}}Other{{/default}}{{/switch}}` | | `titleCase` | Capitalizes the first letter of every word in a string. | `{{titleCase "hello world from the team"}}` → `Hello World From The Team` | --- Source: https://documentation.formspark.io/dashboard/autoresponder.md # Autoresponder The autoresponder automatically sends a confirmation email to the person who submitted your form. The autoresponder is available on [upgraded workspaces](https://documentation.formspark.io/troubleshooting/limits-and-plans.md). ## Enabling the autoresponder To enable the autoresponder for a form, open its `Settings` section, expand `Autoresponder` under `Emails` and press `Create template`. Creating the template turns replies on, and deleting it turns them off. The template is designed in a visual editor, built in partnership with [Postcraft](https://postcraft.io/). Add your own copy and imagery, and include a recap of the submitted data. You can also write the template from your own code, without opening the dashboard at all. See [templates](https://documentation.formspark.io/api/reference.md#templates) in the API reference. ## Who receives the autoresponse Formspark determines the recipient from your form's submission data. It reads the first of the following fields that the submission fills in: 1. `_replyto` 2. `mail` 3. `email` 4. `_email.replyto` `mail` and `email` match in any case, so a field named `Email` works too. ```html ``` If none of these fields is filled in, or the value found is not a valid email address, no autoresponse is sent. ::: tip The same fields also set the reply-to address of your own notification emails, so a form that supports direct replies already works with the autoresponder. ::: ## Replies Replies to an autoresponse go to your form's first notification recipient, so a submitter who answers the confirmation email reaches you, not Formspark. ## Footer and unsubscribe Every autoresponse ends with a footer you cannot remove. It tells the recipient they received the confirmation because they submitted a form on your site, and names that site (or the form, when the site is unknown). It also offers an unsubscribe link to anyone who did not submit it. Recipients who unsubscribe stop receiving autoresponses. ## Subject Set a subject line in the template to replace the default one. It can include the submitted data, such as the visitor's name. A subject that comes out empty, because the fields it names were not filled in, falls back to the default. ## Language The default subject and the footer are in English. Add a hidden `_language` field to send them in your visitor's language. See [Language](https://documentation.formspark.io/customization/language.md) for the supported values. A subject you set in the template is sent as you wrote it, whatever the language. The body is your own template, so write it in the language you want. ## Content policy Use the autoresponder for transactional confirmations, not for marketing or bulk email. ::: warning Spam-flagged submissions never trigger an autoresponse. ::: Every autoresponder template passes a content check. If the check pauses yours, the `Autoresponder` row says so and no replies are sent. Submissions are still stored. Contact support to have the template reviewed. --- Source: https://documentation.formspark.io/dashboard/exporting-submissions.md # Exporting submissions You can easily export your data as JSON or CSV documents. ## Steps 1. Navigate to your form's `Submissions` section 2. Select the submissions you want to export 3. Press `Export` and choose `JSON` or `CSV` ![Export submissions](https://documentation.formspark.io/export-submissions.png) ## Exporting a whole form To export everything a form received over a period, without selecting submissions one by one, use its `Exports` section. 1. Navigate to your form's `Exports` section 2. Choose a format and a period, such as `Last 30 days`, `All time` or a custom range 3. Press `Create export` The export appears in the list below once it is ready. Press `Download` to save it. Exports cover the submissions in your inbox. Deleted and spam submissions are not included. --- Source: https://documentation.formspark.io/dashboard/account-settings.md # Account settings Settings that belong to you rather than to one of your workspaces. Open them from the avatar menu in the dashboard, or go straight to [your settings](https://dashboard.formspark.io/account/api-tokens). Workspace settings, including billing, team members and [deleting a single workspace](https://documentation.formspark.io/dashboard/additional-workspaces.md#deleting-a-workspace), live with the workspace instead. ## API tokens Tokens let scripts and tools use Formspark on your behalf. A token belongs to you and reaches every workspace you are a member of, limited to the scopes you give it. The API itself is available on paid workspaces. A token is shown once, when you create it. If you lose it, revoke it and create another. Revoking takes effect immediately. See [API tokens](https://documentation.formspark.io/api/api-tokens.md) for the scopes, expiry and usage. ## Deleting your account Go to **Settings → Delete account**. You will be shown exactly what is about to be removed and asked to type your email address to confirm. Deletion cannot be undone. Nothing is archived and nothing can be restored afterwards, so export anything you want to keep first. See [exporting submissions](https://documentation.formspark.io/dashboard/exporting-submissions.md). ### What is removed - Every workspace you are the only member of, along with its forms, submissions, notification settings and integrations. - Your membership of workspaces shared with other people. Those workspaces themselves are left alone, together with everything in them. - Your API tokens. Anything still using one stops working immediately. - Your email address, on every form that notifies it. ### What is kept Your sign-in is kept, so you can come back later with the same address rather than registering again. You will arrive with no workspaces. The free submissions included with your original signup are not granted a second time. Any workspace you create after deleting starts empty, and you can add submissions to it with a bundle. See [limits and plans](https://documentation.formspark.io/troubleshooting/limits-and-plans.md). Records we are required to retain for accounting, such as payment records for bundles you have bought, are held by our payment provider and are unaffected. ### Your address is removed from other people's forms too Deleting your account takes your address off every form that sends notifications to it, not only the forms in your own workspaces. That includes forms belonging to people you have never shared a workspace with, if someone added you as a recipient. Aliases of the same mailbox go with it. Deleting an account on `you@gmail.com` also clears `you+forms@gmail.com` and `y.o.u@gmail.com`, because they all deliver to you. If you were the only recipient on someone else's form, that form will no longer notify anyone until its owner adds a new recipient. Tell them before you delete if that matters. ### If you are the only administrator of a shared workspace Deletion is refused while you are the only administrator of a workspace that other people are members of. Removing you would leave that workspace with nobody able to manage it. The dashboard lists the workspaces holding you up. For each one, either: - Promote another member to administrator, then delete your account. The workspace and its data stay with them. See [inviting team members](https://documentation.formspark.io/dashboard/inviting-team-members.md). - Or remove the other members, which turns it into a workspace you are alone in, and it will then be deleted along with everything in it. ### Purchased submissions are not refunded If a workspace being deleted still holds submissions from a bundle, those are lost with it. Bundles belong to a workspace rather than to you, so if you want to preserve one, hand that workspace to another administrator instead of deleting it. --- Source: https://documentation.formspark.io/html-form/form-validation.md # Form validation We recommend using HTML5's built-in validation. It is rich and has good browser support. ::: warning Formspark performs no server-side validation. Validate your inputs client-side before submission to avoid storing malformed data. ::: ## Resources - [MDN: Form data validation](https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Form_validation) - [HTML5 validation browser support](https://caniuse.com/#search=validation) - [MDN: the input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) ## Required fields The `required` attribute is a boolean attribute. When present, it specifies that an input field must be filled out before submitting the form. ```html
``` ## Length constraints Use `minlength` and `maxlength` to constrain text inputs. ```html ``` ## Pattern matching Use `pattern` with a regular expression to enforce a specific format. ```html ``` The `title` attribute is shown by the browser when the pattern fails. ## Custom validation messages Use `setCustomValidity` to replace the default browser message. ```html
``` ## Styling invalid fields CSS pseudo-classes let you style validation state without JavaScript. ```css /* Applies as soon as the field is invalid */ input:invalid { border-color: red; } /* Applies only after the user has interacted with the field */ input:user-invalid { border-color: red; } input:user-valid { border-color: green; } ``` Prefer `:user-invalid` / `:user-valid` over `:invalid` / `:valid` so empty required fields don't appear red on page load. --- Source: https://documentation.formspark.io/html-form/form-styling.md # Form styling With Formspark you get to bring your own HTML and CSS. On this page you'll find tips, tricks and links to help you style your forms. ## Simple vertical layout ![Simple vertical layout](https://documentation.formspark.io/simple-vertical-layout.png) ```html
``` ## Accessible form Pair every input with a `