Grofomo API
Browse the docs

Examples use a fictional festival, summer-fest. Sign in at events.grofomo.com and they switch to your own events.

Submit a form

POST/v1/forms/{key}/submissions

Submit answers for a published form. Answers are validated against the form's own definition, so fetch the definition first and post back matching field ids.

There is no bot check on this endpoint today, so you do not need to render a Turnstile widget.

Send ?surface=webOmit it and the request is treated as coming from the mobile app, which is gated on a different visibility setting — so a perfectly live event can return 404 not_found for no visible reason.
No bot check todayThis write accepts a turnstileToken, but it is not currently verified, so you do not need to render a widget to call it. What gates it is your publishable key and the organiser’s domain allowlist, plus a per-address rate limit. We will announce it in the changelog before a token starts being required.

Request

curl -sS \
  -X POST \
  -H 'X-Grofomo-Key: pk_live_YOUR_PUBLISHABLE_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"answers":{"full_name":"Alex Doe","email":"alex@example.com","shifts":["friday-evening","saturday-morning"]}}' \
  'https://api.grofomo.com/v1/forms/volunteer-signup/submissions?surface=web'

Path parameters

keystringrequired
The form's key. Example: `volunteer-signup`.

Query parameters

surface'web'required
Must be `web` for a website. Omit it and you get the mobile-app surface, which is gated on a different visibility setting — so a perfectly live event can return 404. Example: `web`.

Response

200 OK
{
  "apiVersion": 1,
  "data": {
    "ok": true
  }
}
oktrue
verificationobjectmay be absent
verification.email"sent" | "not_needed" | "failed"
verification.phone"sent" | "not_needed" | "failed" | "unavailable"
verification.phoneHintstring | null
Generated from FormSubmissionResponse

Errors

unauthorizedHTTP 401
No key was sent and the organiser requires one — or the key is invalid, revoked, belongs to another organisation, or is scoped to a different event.
origin_not_allowedHTTP 403
Your site's domain is not on the organiser's allowed list. Browser calls only: a server sends no Origin header and is unaffected.
not_foundHTTP 404
No event with that slug is published on this surface. Check the slug, and check you sent `?surface=web`.
bad_requestHTTP 400
An answer did not match the form definition.

Notes

  • Rate limited to roughly 30 requests per minute per caller. Guidance, not a contract — see caching and rate limits.
  • Cache-Control: no-store