Submission API

POST /api/s/{slug}

Public endpoint for form ingestion with payload validation, spam scoring, and free-tier guardrails.

POST/api/s/{slug}

Use your form slug from the dashboard. If the form is paused, submissions are rejected.

Auth: Public (no API key)

Request requirements

  • Content-Type must include application/json.
  • Body must be a JSON object with scalar values only: string | number | boolean | null.
  • Max encoded payload size is 5KB.

Example request

await fetch("/api/s/contact", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    email: "user@example.com",
    message: "Hello",
  }),
});

Success response

{
  "accepted": true,
  "submission": {
    "id": "sub_...",
    "status": "ACCEPTED",
    "createdAt": "2026-04-26T00:00:00.000Z"
  }
}

Spam behavior

Requests are scored for suspicious patterns (honeypot-style field keys, keyword/url density, repeated characters). When flagged, the API returns 202 with SPAM_REJECTED and does not create a submission row.