Tools
Forms
Contact forms and custom forms with schema-on-write. No form builder needed — just submit data and the schema builds itself.
Two types of forms#
Contact Form
Pre-built with email, name, and message fields. Renders as a widget on your page.
Custom Forms
Accept any JSON payload. Schema auto-infers from submissions. Each form gets a unique key.
Contact form widget#
The built-in contact form renders as a Shadow DOM widget with email, name, and message fields.
<!-- Renders a contact form with email, name, message --><div data-os-widget="form" data-os-form="contact"></div>| Property | Type | Description |
|---|---|---|
| heading | string | Widget heading text (default: "Get in touch") |
| description | string | Subtitle below the heading |
| buttonText | string | Submit button label (default: "Send") |
| successMessage | string | Message shown after submission (default: "Thanks for reaching out!") |
| fields | string[] | Visible fields: "email", "name?", "message?" |
Custom forms#
Custom forms use a schema-on-write approach: you don’t define fields upfront. The schema is inferred from the first submission and extended with each new one.
Form keys#
Every custom form gets a unique key (e.g., frm_abc123). Use this key for API submissions and SDK calls.
Public form endpoint#
Submit to any form using its form key. No authentication required. Accepts JSON, form-urlencoded, or multipart data.
# JSONcurl -X POST https://api.operatorstack.dev/v1/f/frm_abc123 \ -H "Content-Type: application/json" \ -d '{"email": "user@example.com", "company": "Acme Inc"}' # Form-urlencodedcurl -X POST https://api.operatorstack.dev/v1/f/frm_abc123 \ -d "email=user@example.com&company=Acme+Inc"Reserved fields#
Fields prefixed with an underscore are metadata — they’re processed but not stored in the submission data.
| Property | Type | Description |
|---|---|---|
| _redirect | string | URL to redirect to after submission (returns 303) |
| _subject | string | Email notification subject line |
| _formName | string | Display name for the form in notifications |
SDK usage#
// Submit to a custom formawait window.OperatorStack.submitForm('frm_abc123', { email: 'user@example.com', company: 'Acme Inc', budget: '$10k-50k'}) // Send a contact messageawait window.OperatorStack.sendContactMessage({ email: 'user@example.com', name: 'Jane Doe', message: 'I have a question about pricing.'})Plain HTML form#
You can submit to custom forms using a standard HTML form — no JavaScript needed. Add a _redirect hidden field to redirect after submission.
<form action="https://api.operatorstack.dev/v1/f/frm_abc123" method="POST"> <input type="email" name="email" placeholder="Email" required /> <input type="text" name="company" placeholder="Company" /> <textarea name="feedback" placeholder="Your feedback"></textarea> <input type="hidden" name="_redirect" value="https://yoursite.com/thanks" /> <button type="submit">Submit</button></form>API endpoints#
/v1/f/{form_key}Public/v1/projects/{projectKey}/contactPublicSubmission management#
Every submission has a status that helps you triage incoming data:
- New — fresh submission, not yet reviewed
- Read — you’ve seen it
- Archived — processed and filed away
Filter submissions by status in the dashboard. Status changes are logged to the audit trail.
CSV export#
Export submissions to CSV from the dashboard. Columns are auto-generated from the form schema with a submitted_at timestamp. Exports include UTF-8 BOM for Excel compatibility and are capped at 10,000 rows.
Dashboard features#
- Auto-generated table columns from submission schema
- Form configuration panel with heading, description, and button text
- Submission count and recent activity
- Status management (new, read, archived) with filtering
- CSV export of submissions
- Setup tab with copyable code snippets for 4 integration patterns: HTML form, JavaScript SDK, HTTP API, and AI prompt