Documentation
Use Better Form as a hosted form backend: submit responses externally, receive webhook alerts, and fetch response data with separate API keys.
https://betterform.dev/apibf_sub_... for external writes and webhook signatures.bf_data_... for read-only response exports.POST /submit/{publicId}Send response payloads from your own frontend or server.
POST your webhook URLReceive real-time response notifications signed with your submission key.
GET /forms/data/{dataApiKey}Export response data in JSON with lightweight rate limiting.
Authenticate with Authorization: Bearer {submissionApiKey} and send a responses object keyed by field IDs.
fetch("https://betterform.dev/api/submit/{publicId}", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer bf_sub_your_submission_key_here"
},
body: JSON.stringify({
responses: {
field_name: "Ada Lovelace",
field_email: "ada@example.com"
}
})
})Better Form includes an `X-BetterForm-Signature` header for each webhook request. Verify it before trusting the payload.
import crypto from "crypto"
function verifyWebhook(payload, signature, submissionApiKey) {
const expected = crypto
.createHmac("sha256", submissionApiKey)
.update(JSON.stringify(payload))
.digest("hex")
return signature === expected
}Use the data key in the path. Responses are rate limited to one request every five seconds per form.
fetch("https://betterform.dev/api/forms/data/{dataApiKey}", {
headers: { Accept: "application/json" }
})
.then((res) => res.json())
.then((data) => console.log(data.responses))