Each form has its own address, shown on its Install tab:
POST https://intake.starstorm.dev/api/form/<form id>/submission
It accepts three kinds of body:
- An HTML form post (
application/x-www-form-urlencoded): the visitor is redirected to your thank-you page, or Intake's own. - JSON (
application/json), or any post withAccept: application/json: the answer is JSON. - File uploads (
multipart/form-data), on plans with uploads: each file field becomes an object with its name, type, size and a download link.
<form
action="https://intake.starstorm.dev/api/form/<form id>/submission"
method="POST">
<input name="email" type="email" required>
<textarea name="message"></textarea>
<!-- the honeypot: hide it with CSS; bots fill it in -->
<input name="fc_honeypot" style="display:none"
tabindex="-1" autocomplete="off">
<button>Send</button>
</form>const url =
"https://intake.starstorm.dev/api/form/<form id>/submission";
const res = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
email: "ada@example.com",
message: "Hello",
}),
});
// { id, formId, data, domain, createdAt, ... }
const submission = await res.json();
Errors
JSON callers get an HTTP status and {"message": "...", "name": "..."}:
| Status | name | Why |
|---|---|---|
| 400 | badRequestError | The sending site is not in the form's allowed domains, or the body is not valid |
| 403 | forbiddenError | The form is not accepting submissions |
| 404 | notFoundError | No such form |
| 422 | validationError | The form enforces its expected fields; errors says which failed |
| 429 | rateLimitError | Too many posts from one address or to one form; retry shortly |
Over your monthly limit, submissions are held, not refused: the answer is 200 with "held": true, and the submission appears once the quota allows.