Collecting forms from React Native means POSTing JSON to the same submit URL as your website, with field names matching the dashboard schema and an ingest secret on production traffic. Submissions appear in the same inbox as embed leads—no WebView survey required.
Guide
POST JSON from React Native or Expo to the same form backend as your website—field schemas, ingest secrets, validation errors, and one inbox for support.
| Step | Action |
|---|---|
| 1 | Create form + field names in dashboard |
| 2 | Generate ingest secret |
| 3 | POST JSON from fetch() |
| 4 | Handle 422 validation in UI |
| 5 | Prefer API proxy so secret stays off-device |
Your marketing site has a contact embed. Your iOS app still uses a WebView to Google Forms—or worse, email mailto: links. Collecting forms from React Native properly means native inputs, one JSON POST, and the same inbox support searches when a user says they “sent feedback from the app.”
This pillar guide covers schema alignment, fetch examples, ingest secrets, validation errors, and when to proxy through your API so secrets never ship in the app binary.
Website: embed.js --POST--> MuxForms inbox
App: fetch JSON ----POST--> same form id --> same inbox
Create fields in the MuxForms dashboard (email, message, optional platform). The website embed renders them automatically; the app must send matching keys.
Deep dive: Expo + website tutorial.
Docs: React Native and submit API.
const FORM_ID = process.env.EXPO_PUBLIC_MUXFORMS_FORM_ID!;
const SUBMIT_URL = `https://www.muxforms.com/api/v1/forms/${FORM_ID}/submit`;
async function submitFeedback(email: string, message: string) {
const res = await fetch(SUBMIT_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.MUXFORMS_INGEST_SECRET}`,
"X-MuxForms-Ingest-Secret": process.env.MUXFORMS_INGEST_SECRET!,
},
body: JSON.stringify({
email,
message,
platform: "ios",
_hp: "",
}),
});
const data = await res.json().catch(() => ({}));
if (!res.ok) throw new Error(data.error ?? `HTTP ${res.status}`);
}
Production apps should not embed MUXFORMS_INGEST_SECRET in client env vars if the binary is public—use a backend proxy (below).
Browser embeds use CORS + submit tokens. Mobile uses per-form ingest secret headers:
Authorization: Bearer ingsec_…X-MuxForms-Ingest-Secret: ingsec_…Generate in dashboard → form security. Rotate if leaked.
Recommended: Next.js or Cloudflare Worker route:
// POST /api/feedback from app --> server adds secret --> MuxForms
Pattern also used in Next.js contact tutorial.
| Status | User-facing message |
|---|---|
| 422 | “Check required fields” — log server field errors in dev |
| 403 | “Could not send” — secret, paused form, or subscription |
| 429 | “Try again in a minute” |
| Network | Offline / corporate proxy |
Map validation messages to inputs when the API returns field-level detail.
Native iOS/Android: no CORS. Expo Web and React Native Web: allowlist http://localhost:8081 or your web preview origin on the form—see CORS guide.
Honeypot _hp still applies if bots hit your API directly. Rate limits protect the endpoint. Turnstile is browser-first; mobile relies on secret auth and optional server attestation (out of scope for basic contact forms).
More: spam guide.
Compare positioning: MuxForms vs Typeform.
platform field.If you are deciding whether you need hosted ingest at all, read What is a form backend?. If you only need email from HTML, read HTML form to email without backend.
Not every “Formspree alternative” documents native POST well—use the compare hub tables (mobile JSON row) and Formspree-style roundup.
MuxForms is the inbox, embed, and JSON API. Start free, or upgrade to Pro or Team.
Upgrade to Pro