Integrating means pointing something at the endpoint and deciding where submissions go. Pick the surface that matches your stack.
Plain HTML form
The simplest integration: set the form action to your endpoint_url and let the browser POST. Because the browser sends Accept: text/html, the visitor is redirected to /thanks/{form_id} on success. No JavaScript required.
<form action="https://api.lanes.sh/v1/f/YOUR_FORM_ID" method="POST">
<input type="email" name="email" required />
<textarea name="message"></textarea>
<!-- honeypot: bots fill this, humans never see it -->
<input type="text" name="_gotcha" style="display:none" tabindex="-1" />
<button type="submit">Send</button>
</form>Keep the hidden _gotcha input in your markup. It is the honeypot that silently absorbs bots.
fetch / AJAX
For a custom UI, POST JSON and handle the receipt yourself:
const res = await fetch("https://api.lanes.sh/v1/f/YOUR_FORM_ID", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email, message, _gotcha: "" }),
});
const { ok, submission_id } = await res.json();Never put an API key in browser code
Browser submissions are authorized by the form's allowed_origins, not by a secret. A workspace key shipped to the browser is a leaked key. Keep public, browser-facing forms in open mode with an origin allowlist. See Securing your endpoints.
Server-side
From a backend, POST JSON the same way you would with curl. If the form is in api_key mode, add the workspace key as a bearer token:
curl -X POST https://api.lanes.sh/v1/f/YOUR_FORM_ID \
-H "Content-Type: application/json" \
-H "Authorization: Bearer lfk_YOUR_KEY" \
-d '{"email": "visitor@site.com", "message": "Hello!"}'Where submissions go
Delivery is configured per form as a list of workflow actions. Two are live today:
| Action | Status | What it does |
|---|---|---|
email | Live | Forwards each non-spam submission to your verified recipients (up to 5). |
store (lanes) | Live | Keeps submissions in Lanes-hosted storage, viewable and exportable from the dashboard. |
store (custom) | Coming soon | Your own database, such as Supabase. Returns 422 action_not_available today. |
webhook | Coming soon | POST each submission to your URL. Returns 422 action_not_available today. |
Email forwarding
Adding a recipient sends a confirmation link (GET /v1/verify-email/{token}). Until a recipient confirms, it is silently skipped, so unverified addresses never receive mail. When a form is claimed with recipients, the first one is verified for you and forwarding starts.
Forwarding waits for a claim
An unclaimed form stores submissions but forwards nothing. Delivery activates the moment the form is claimed.
The thank-you page
Browser posts land on a hosted /thanks/{form_id} page. A per-form redirect override (sending visitors to your own thank-you URL) is on the roadmap.
Next: Securing your endpoints and API keys.