Skip to content
← All migration guides

Migrate · Formspark

Migrate from Formspark to Formward

Formspark and Formward work the same way: your form posts to an endpoint, and the service stores, filters and emails the submission. Formspark's docs use https://submit-form.com/ plus your form ID as the action, nest email settings under _email (such as _email.subject), and accept _honeypot or _gotcha as the honeypot.

Both keep submission data in the EU, so this move is usually about the pricing model, file storage or the hosting provider rather than residency. The comparison page covers that side.

Last checked 7 October 2026. What this guide says about Formspark comes from Formspark's own documentation, listed under Sources. Check their current docs if something looks different in your account. The Formward side is the reference in the migration docs.

The change

Change the action URL and rename the subject and honeypot fields. _redirect keeps its name.

Before: Formspark, HTML

<form action="https://submit-form.com/YOUR_FORM_ID" method="POST">
  <input type="email" name="email" required>
  <textarea name="message" required></textarea>
  <input type="hidden" name="_email.subject" value="New enquiry">
  <input type="hidden" name="_redirect" value="https://example.com/thanks">
  <input type="text" name="_honeypot" style="display:none">
  <button type="submit">Send</button>
</form>

After: Formward, HTML

<form action="https://forms.formward.eu/f/<formId>" method="POST">
  <input type="email" name="email" required>
  <textarea name="message" required></textarea>
  <input type="hidden" name="_subject" value="New enquiry">
  <input type="hidden" name="_redirect" value="/thanks">
  <input type="text" name="_gotcha" style="display:none" tabindex="-1" autocomplete="off">
  <button type="submit">Send</button>
</form>

Before: Formspark, JSON

await fetch("https://submit-form.com/YOUR_FORM_ID", {
  method: "POST",
  headers: { "Content-Type": "application/json", Accept: "application/json" },
  body: JSON.stringify({ message, _email: { subject: "New enquiry" } }),
});

After: Formward, JSON

await fetch("https://forms.formward.eu/f/<formId>", {
  method: "POST",
  headers: { "Content-Type": "application/json", Accept: "application/json" },
  body: JSON.stringify({ message, _subject: "New enquiry" }),
});

Field and feature mapping

FormsparkFormwardNotes
https://submit-form.com/{id}https://forms.formward.eu/f/<formId>The only change to the form tag.
_email.subject_subjectSubject of the notification email.
_redirect_redirectSame name. Must be a relative path or a URL on an allowed origin.
_errornoneA failed classic post shows Formward's error page. Handle errors in JavaScript if you need your own.
_honeypot or _gotcha_gotchaFormward's honeypot name is fixed.
_replyto, email, mail, _email.replyto_replyto, _reply_to or emailFormward reads _replyto, then _reply_to, then a field named email. Rename a mail or _email.replyto field to email or _replyto.
_email.from, _email.template.*Form settingsNotification design is set on the form; custom email branding is on Business.
_botpoison, g-recaptcha-response, h-captcha-responsecf-turnstile-responseFormward supports Cloudflare Turnstile, optional per form.
Link from Uploadcare, S3 or similarfile input, multipartKeep the link (stored as text) or switch to native uploads on Professional and up (5 files of up to 10 MiB each on Professional).

What changes, what stays

Changes

  • The action or fetch() URL.
  • _email.subject becomes _subject, and _honeypot becomes _gotcha.
  • Reply-To comes from _replyto, _reply_to or a field named email. A mail or _email.replyto field is renamed to email or _replyto.
  • Captcha widgets other than Turnstile are removed.

Stays the same

  • _redirect keeps its name.
  • Your other field names; every named field is stored as sent.
  • URL-encoded and JSON bodies both work, and so does Accept: application/json.

Differences to test before you switch

Specific to Formspark

  • Formspark appends the submitted data to the _redirect URL unless you send _append=false. Formward redirects to the URL as given, without the form data.
  • Formspark accepts email, mail, _replyto or _email.replyto for replies. Formward reads _replyto, _reply_to and email, so a plain email field keeps working; rename a mail or _email.replyto field to email or _replyto.
  • Formspark's docs say a file input does not work with it directly; files go through a third-party uploader and Formspark stores the link. You can keep that widget, since the link is just a text field, or switch to a plain file input with multipart, which Formward stores in Sweden.

How Formward behaves

  • JSON responses. Send Accept: application/json and a success is a 200 with { ok: true, id }. An error is { ok: false, error } with a status code. Without that header, a successful post redirects or shows Formward's thanks page. Code that only checks res.ok keeps working.
  • Status codes. 402 when the plan's monthly submission limit is reached (the body has upgrade: true), 422 when a field fails a validation rule set on the form or required consent is missing, 429 when one address posts too often (with a Retry-After header), and 403 when the origin is not allowed, the Turnstile check fails or files are sent on a plan without uploads.
  • File uploads. Uploads need enctype="multipart/form-data" and a plan that includes them: Professional and up (5 files of up to 10 MiB each on Professional). On Free and Personal a post that carries files is refused with 403, so test an upload before you switch a form that takes attachments.
  • Redirects. A hidden _redirect is followed only if it is a relative path or a URL on one of the form's allowed origins; otherwise it is ignored and the redirect set on the form applies, then Formward's thanks page. JSON (AJAX) requests are never redirected.
  • Spam. If the _gotcha honeypot is filled in, the sender gets a normal success response, but the submission is stored as spam, sends no notification and does not count toward your quota. Rate limits apply on every plan; Cloudflare Turnstile and disposable-email blocking are optional per form.
  • Allowed origins. With the list empty, any site can post to the endpoint. Once you add an origin, requests whose Origin header does not match are refused with 403, including server-side requests that send no Origin header.
  • Reply-To. The Reply-To of the notification email is taken from _replyto, then _reply_to, then a field named email. So a plain email field sets Reply-To with no rename, and _replyto only overrides it, for example when the email field has another name or the form has several. An invalid address is dropped, and the email then has no Reply-To.

Every status code and body is listed in responses and redirects.

History, integrations and settings

  • Formspark's docs describe exporting submissions from its dashboard as JSON or CSV. Formward's CSV importer (Dashboard, Import & migrate) takes any CSV with a header row, up to 5,000 rows and 10 MB per file. Imported rows send no email and do not count toward your quota. Each row keeps its original date when the file has a column named Submitted At, created_at or createdAt; otherwise it is dated at import time. Attached files are not imported, only cell values.
  • Forms on the Free plan keep submissions for 30 days, and the nightly retention sweep deletes imported rows older than a form's retention window. To keep a longer history, import into a form on a paid plan with a long enough window.
  • Webhooks, Slack, Google Sheets, Notion, Zapier and Make connections and the autoresponder belong to your Formspark account and do not move with the endpoint. Recreate the ones you need: Formward webhooks (including Slack, Discord, Teams and Mattermost), Google Sheets and Baserow sync start on Professional, the autoresponder on Professional, and extra notification recipients on Personal.

Pricing and data location

  • Formspark sells submissions as a one-time bundle: a free tier of 250 submissions and an upgrade with 50,000, which it says do not expire. For a low-traffic site that is cheaper than any Formward paid plan.
  • Formspark is operated by Trampoline Software SRL in Belgium and keeps its data in the EEA, with hosting on AWS in Ireland.
  • Formward is priced in euros: Free with 50 submissions a month, then Personal at EUR 15, Professional at EUR 30 and Business at EUR 90 a month (EUR 10, 20 and 60 billed yearly).
  • Formward stores and processes submissions at Hostup AB in Sweden and sends notification email through Mailjet in the EU. The one optional non-EU sub-processor is Cloudflare Turnstile, on forms where you switch it on.

The full side-by-side, with sources, is in Formward vs Formspark. Formward's prices are on the plans page, and where each part of Formward runs is on EU data residency.

Step-by-step checklist

  1. Create the form. In the Formward dashboard, create a form, set the notification email and copy the endpoint.
  2. Change the action. Replace the submit-form.com URL in the form's action, or in your fetch() call, with the Formward endpoint.
  3. Rename the special fields. _email.subject becomes _subject, _honeypot becomes _gotcha. A plain email field keeps setting Reply-To; rename a mail or _email.replyto field to email or _replyto.
  4. Decide on uploads. Keep your third-party upload widget, or replace it with a file input and multipart encoding on a plan with uploads.
  5. Restrict origins. Add your site's origin, for example https://www.example.com, to the form's allowed origins. Leave the list empty if you also post from a server.
  6. Test before you switch. Point a copy of the form at Formward and send a few entries: a normal one, one with the honeypot filled, and one with a file if the form takes uploads. Check the dashboard and the notification email.
  7. Recreate integrations. Set up webhooks, Sheets or Baserow sync and the autoresponder on the Formward form.
  8. Bring the history. If you want past submissions, export them as CSV from your old provider and import them under Dashboard, Import & migrate.
  9. Retire the Formspark form. Switch the live form, watch the first real submissions arrive, then disable the form at Formspark so nothing is split between two inboxes.

Sources

Last checked 7 October 2026

Move one form first

The free plan takes 50 submissions a month with no card. Point a copy of one form at Formward, send a few test entries, and switch the live form once the path works end to end.

Migrate from Formspark to Formward