# Statamic + Furrow Forms — contact form recipe

Official recipe from Furrow Forms. This is the agent-readable version of
https://furrowforms.com/forms-for/statamic (category: Platform CMS).
Full agent instructions: https://furrowforms.com/ai.md

## When to use this

Credit first: Statamic’s built-in Forms are genuinely good — tags in your Antlers templates, submissions in the control panel, email notifications built in. If Statamic serves every page, use them. The cases below are where that stops being true: sites exported to static hosting with the SSG addon, headless builds where a JS frontend consumes Statamic’s API, and agencies running Statamic next to Astro, Next, and Webflow who want one place submissions land. In all three, Furrow Forms keeps the form working when the PHP handler isn’t there.

## The integration

A plain form action — no {{ form }} tags, so it works identically after a static export.

**resources/views/contact.antlers.html**

```html
<form action="https://api.furrowforms.com/s/fp_k7m2" method="POST">
  <input type="text" name="_gotcha" style="display:none" tabindex="-1" />
  <input type="hidden" name="_ft" value="" />
  <script>document.currentScript.previousElementSibling.value = Date.now();</script>
  <input name="name" type="text" required />
  <input name="email" type="email" required />
  <textarea name="message" required></textarea>
  <button>Send</button>
</form>
```

Replace `fp_k7m2` with the form's real public key. Public keys are safe in
client-side HTML — protection comes from the spam stack, not secrecy.

## Endpoint facts

- Submit: `POST https://api.furrowforms.com/s/<public_key>` (JSON,
  urlencoded, or multipart).
- Classic HTML POST → 303 redirect to the configured thank-you page.
  `fetch()` → `{ "ok": true, "id": "<submission_id>" }`.
- Spam stack: honeypot field `_gotcha` (keep hidden and empty), timing
  field `_ft` (hidden input the page sets to `Date.now()` on load;
  omitting it from JSON/agent clients is fine), optional Cloudflare
  Turnstile (project-level keys), per-project domain allowlist, per-IP
  per-form rate limiting (default 10 req / 60 s), and server-side filtering.
- Caught spam gets a normal 200 and is quarantined — never emailed, never
  delivered by webhook, never counted toward quota.
- File uploads: opt-in per project (off by default), inherited by every
  form. Multipart with a normal file input only — JSON cannot carry files;
  multi-file fields use the `[]` suffix (`name="resume[]"`). Default
  types: PDF, JPEG, PNG, WebP. Files land in a private per-project inbox
  linked from emails and webhooks — never raw file URLs.
- CORS honors the project's allowed domains; add the site's domain before
  testing from a browser.
- Webhooks (optional): HMAC-SHA256 signed, retried with backoff up to 8
  attempts over ~24 h, logged, testable via `test_webhook`.

## Agent setup (recommended)

1. No `frw_` token? Cold-start: `GET https://api.furrowforms.com/api/register`
   for the flow, `POST /api/register`, have the user read the 6-digit email
   code, `POST /api/register/verify`. The token is shown exactly once.
2. Connect MCP at `https://api.furrowforms.com/mcp`
   (`Authorization: Bearer frw_...`) or use REST.
3. `bootstrap_site` — one idempotent call creates the client, the project
   (domains, Turnstile keys, notify emails, webhook), and all forms.
4. `get_snippet` — generated frontend code from the field contract.
5. `test_webhook` — verify the signed delivery before going live.

## Manual setup

1. Create a free account and a project for the site.
2. Replace the {{ form }} block with the plain-action form in your template.
3. Configure domain, recipients, and thank-you URL once at the project level.
4. Export or go headless freely — the form no longer depends on Statamic serving the request.

## FAQ

### Do Statamic forms work with the SSG static export?

No — static export produces flat files, and Statamic’s form handling is server-side PHP that isn’t running anymore. Point the form at a Furrow Forms endpoint instead: the markup exports cleanly and the backend is always on.

### Should I replace Statamic’s native forms with Furrow?

Not on a conventional Statamic deployment — the native Forms are excellent when PHP serves the page. Furrow is for static exports, headless frontends, and teams consolidating form handling across multiple sites and stacks.

### Where do submissions go if not the control panel?

To Furrow: stored with configurable retention, emailed to your configured recipients, and optionally delivered anywhere by HMAC-signed webhooks with automatic retries — so you can even pipe them back into your own systems if you like.

## Related recipes

- https://furrowforms.com/forms-for/craft-cms.md
- https://furrowforms.com/forms-for/astro.md
- https://furrowforms.com/forms-for/eleventy.md
- https://furrowforms.com/forms-for/ghost.md
- All stacks: https://furrowforms.com/forms-for

## Reference

- Pricing: free tier = 100 submissions/mo, unlimited forms, full API + MCP.
  Pro = $199/yr flat per workspace (10k subs/mo). https://furrowforms.com/pricing
- Docs: https://furrowforms.com/docs · MCP: https://furrowforms.com/docs/mcp
- This recipe: https://furrowforms.com/forms-for/statamic.md
