Forms
Public endpoint for receiving form submissions from websites. No API key required — safe for client-side JavaScript.
POST /f/{form_id}
body object requiredArbitrary JSON — any form fields
Request example
Response
Form Fields
Any fields are accepted. Standard fields are highlighted in notifications and will be used in future integrations (CRM, Google Sheets).
name string Sender name
email string Sender email
phone string Phone number
subject string Subject
company string Company
city string City
url string Website URL
message string Message text
* any Any other fields — passed as-is
allowed_origins format
Allowed origins are specified as domains. Scheme (http/https), www and slashes are normalized automatically — just write example.com and all variants (https://example.com, www.example.com, example.com/) will be accepted.
example.com — accepts submissions from https://example.com, http://example.com, https://www.example.com
*.example.com — any subdomain and example.com itself (requires at least second level, *.com is forbidden)
Local hosts (localhost, 127.0.0.1), private IPs and reserved TLDs (.local, .test, .example) are forbidden — the server returns an error on save
Security
Origin check — only allowed domains
Rate limit — 30 submissions/min per form
Honeypot — hidden _honey field to protect from bots
Sanitization — automatic HTML tag and dangerous content removal
Time-to-submit — minimum fill-time check. Default is 3 seconds (JS snippet sends `_submit_time` automatically). For plain HTML forms without JavaScript — set to 0 in form settings.
Blocklist of throwaway email services (mailinator, tempmail, …) — flagged as spam
Spam folder & filters
Spam submissions are NOT deleted — they go to a separate list for review. Webhooks and email notifications skip spam.
Spam tab in dashboard — separate list of flagged submissions
Honeypot — hidden field with a unique per-form name. If a bot fills it, the submission is silently rejected
Keyword blocklist — customizable word list. Matches are flagged as spam
Timestamp check — `_submit_time` set on page load, verified on submit (default 3 seconds). The JS snippet sends it automatically. For plain HTML forms without JS — disable the check (0) in form settings, otherwise submissions land in spam with reason 'missing_timestamp'.
Manually mark submissions as spam/not-spam in the dashboard
Submission Routes (Form Routes)
Unified model: route = trigger + action. Trigger — «always» (default recipient) or «conditional». Actions: deliver to recipient / mark as spam / block. Up to 40 routes per form.
Condition operators: `contains` (substring), `equals` (exact match). Condition field — field name or `*` for any string field
`mark_spam` — save, but flag as spam (no delivery, no webhook)
`block` — don't save at all (silent 200 OK)
`deliver` — deliver to recipient (email/messenger/subscriber/team). Conditional route adds to always-routes by default
Flag `replace_defaults` on a conditional deliver-route replaces all always-routes when matched — use for re-routing (e.g. «only sales submissions → sales@»)
Post-submit redirect
If `redirect_url` is set in form settings and the request came as `application/x-www-form-urlencoded` (HTML form, no JS), the server responds with `303 See Other` and `Location: <redirect_url>`. JSON requests (fetch/AJAX) still get `{ok:true}`.
Recipients: messengers (Telegram/Max), email, project subscribers
HTML form (no JavaScript)
The simplest integration path. The form works like a regular HTML submit — the browser POSTs to the endpoint. Protection: honeypot + filters. Set the Redirect URL in settings to show a thank-you page after submit.
Fetch / SPA
For single-page apps and dynamic forms. Returns `{ok:true}` JSON. Always handle `{ok:false, error}` and network errors. In the dashboard under «Integration Code → JavaScript» you get a constructor with flexible settings: 30-second timeout on the first attempt (Formspree-style), retry on 5xx/network, localStorage queue, and an idempotent `_request_id` — submissions survive short backend outages and aren't duplicated on retry.