Skip to main content

JavaScript API

For dynamic applications (React, Vue, etc.), you can submit forms using fetch() with JSON.

Basic usage

const response = await fetch('https://api.webstadia.com/v1/fm/YOUR_FORM_ID', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
data: {
name: 'John Doe',
email: 'john@example.com',
message: 'Hello from my app!'
}
})
})

const result = await response.json()
// { status: 'submitted' }

React example

function ContactForm() {
const [status, setStatus] = useState('idle')

async function handleSubmit(e) {
e.preventDefault()
setStatus('submitting')

const formData = new FormData(e.target)
const data = Object.fromEntries(formData)

try {
const res = await fetch('https://api.webstadia.com/v1/fm/YOUR_FORM_ID', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ data })
})

if (res.ok) {
setStatus('success')
e.target.reset()
} else {
setStatus('error')
}
} catch {
setStatus('error')
}
}

return (
<form onSubmit={handleSubmit}>
<input name="name" placeholder="Name" required />
<input name="email" type="email" placeholder="Email" required />
<textarea name="message" placeholder="Message" />
<button type="submit" disabled={status === 'submitting'}>
{status === 'submitting' ? 'Sending...' : 'Send'}
</button>
{status === 'success' && <p>Thanks! We'll be in touch.</p>}
{status === 'error' && <p>Something went wrong. Please try again.</p>}
</form>
)
}

With CSRF protection

For enhanced security, you can use CSRF tokens. First, generate a token:

// Get a CSRF token
const tokenRes = await fetch('https://api.webstadia.com/v1/fm/YOUR_FORM_ID/csrf')
const { token } = await tokenRes.json()

// Submit with the token
const response = await fetch('https://api.webstadia.com/v1/fm/YOUR_FORM_ID', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
csrf: token,
data: {
name: 'John Doe',
email: 'john@example.com'
}
})
})

CSRF tokens are single-use and expire after 60 hours.

Response format

Success

{ "status": "submitted" }

Error — Invalid CSRF token

{ "status": "error", "message": "Invalid or missing CSRF token" }

Error — Form not found

{ "status": "error", "message": "Form not found" }

Spam protection in JSON mode

If you're not using CSRF tokens, you can still use honeypot protection:

const response = await fetch('https://api.webstadia.com/v1/fm/YOUR_FORM_ID', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
data: {
name: 'John',
email: 'john@example.com',
_gotcha: '' // Leave empty — bots will fill this
}
})
})

If _gotcha has a value, the submission is silently rejected (returns success to not tip off the bot).