Online Forms for Developers

Keep your own markup, your own framework, your own deploy. Point the submit at one URL and every response lands in an inbox with notifications, webhooks and exports already wired.

Sound familiar?

What slows developers down.

The contact form that needs a server

A static site is done until someone asks for a form. Then it needs a route, a mail library, a database table and somewhere to host all three.

A migration for every new field

Adding a “company size” question should not mean a schema change, a deploy and a backfill.

Uploads, spam and retries, again

Every hand-rolled form handler rebuilds the same file validation, rate limiting and webhook retry logic, and usually skips one of them.

What you get

Built for the way developers work.

See all features

One endpoint, any JSON

POST any body to /v1/submit/:publicKey. New keys become new columns. Nothing to migrate, nothing to redeploy.

Works with zero JavaScript

A plain <form action> is the whole integration. Static hosts, CDNs and legacy templates all work.

File uploads handled

Send multipart and files are stored for you, behind an allowlist that rejects executables before they are written.

Rate limited per Public Key

Each Public Key gets its own budget, so one noisy client never eats another one’s quota.

Webhooks with a delivery log

Stream each submission into your own system and see exactly what was sent and what came back.

Same inbox as the builder

Teammates who do not write code can read, filter and export the same responses, or build a hosted form of their own.

How it works

Up and running in three steps.

  1. 1

    Create a form and copy its Public Key

    Sign up, create a form, and copy the Public Key from its settings. It is the final segment of the submit URL.

  2. 2

    Point your form or fetch call at the endpoint

    Use the complete URL as a form action, or POST JSON to it from your code. No Authorization header or hidden field needed.

  3. 3

    Connect where the data should go

    Turn on email notifications, a webhook, or a Google Sheets, Slack or Notion connection. Every response follows it.

fetch
await fetch("https://api.surveyowl.co/v1/submit/sk_live_…", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    email: "ada@example.com",
    plan: "pro",
    message: "Hello from my own front end",
  }),
});
FAQ

Questions, answered.

No. Point a plain HTML form action or a fetch call at your form-specific submit URL and responses are stored, notified and exported for you. A server is only useful if you want to keep the Public Key out of the browser, and then it is a few lines that relay the request.

JSON bodies, classic URL-encoded form posts, and multipart requests when you are sending files. New keys in the body become new columns in the inbox automatically.

The Public Key only allows submitting to that one form, and each Public Key has its own rate limit. If you would rather not expose it, proxy the request through a server route that reads the Public Key from an environment variable.

Add a webhook and each submission is POSTed to your URL as it lands, with a delivery log on every plan. You can also export CSV or connect Google Sheets, Notion, Airtable or Zapier.

Any that can send an HTTP request or render a <form>: plain HTML, React, Next.js, Vue, Nuxt, Astro, Svelte, Angular, and site builders like WordPress, Webflow and Framer.