Integrations
What a Form can do beyond storing a Submission, in three families: Sources bring Submissions in, Facets are carried by every Submission, and Steps run when something happens to one.
Every Integration is switched on per Form, on the Form's Integrations tab, and has its own page there. Which ones a Form can have depends on its kind. The tab bar never changes when you switch one on; a dot lights instead.
| Family | What it is | Today |
|---|---|---|
| Source | A door a Submission comes in through, besides the POST. | Slack, email |
| Facet | Something every Submission of the Form carries. | Status, Checks |
| Step | Something that runs when something happens to a Submission. | Webhooks, Gate, Auto classify, Newsletter, Email the team, Post to Slack, Bot protection |
The survey page, MCP and CSV import are also doors, but every Form has them. They are described on Sources, with what each records.
When they run
Bot protection runs first, at the door, before any hook: a Submission it refuses is never stored, so nothing below runs for it.
- Before store: before a Submission is saved. Status gives it the first word here, so it arrives with one.
- After store: once it is saved, after the door has answered. The steps run in a
fixed order: Webhooks deliver
submission.created, then the Gate and Auto classify run, and only then cansubmission.acceptedgo out. - On status change: when a person moves it. Webhooks send
submission.status_changed, and a Source that can answer tells the sender. - On schedule: once a day, across every Form, for work that has to be retried.
A step that fails does not stop the next one, and never delays the door's answer.
Post to Slack
Any Form, of either kind, can post each new Submission to a Slack channel: its Fields, the Submission's id and a link back to the Studio. It posts through an Incoming Webhook you make in your own Slack, so nothing is installed from Noonmark, and each Form can post to its own channel in any Slack workspace.
Making the webhook
- At api.slack.com/apps, Create New App → From scratch.
Name it (the posts show as this name, e.g.
Noonmark) and pick the Slack workspace to post to. - In the sidebar, under Features, open Incoming Webhooks and switch Activate Incoming Webhooks on.
- Add New Webhook, pick the channel and Allow. A private channel is only listed if you are in it. If your workspace restricts apps, an admin approves the request first.
- Copy the webhook URL from the table:
https://hooks.slack.com/services/T…/B…/…. - Optional: under Basic Information → Display Information, give the app an icon, so its posts are easy to tell apart.
One webhook posts to one channel. For another channel, add another webhook to the same app.
Switching it on
On the Form's Integrations → Post to Slack, tick Post every Submission to Slack, paste the URL, and Check and save. Before the URL is kept, the check posts a message to the channel saying Noonmark is connected, with a preview of a post under the Form's own Field labels, so a wrong URL fails there, not on the first Submission. Last post shows how the most recent Submission went.
The URL is a secret: whoever has it can post to that channel. The Studio never shows it again, only its last characters. Leave the field blank to keep it; paste a new one to replace it.
| What | How |
|---|---|
| The message | The Form's name, then its Fields in order, one line each (Label: value; a long answer is quoted under its label). Below, one line of metadata: where it came from, when (in each reader's own time zone), the Submission's id and a link to it in the Studio. Links in it do not unfurl. |
| Someone else's words | The payload and the Form's name are escaped, so a Submission cannot ping @channel, mention anyone or forge a link. Long values are clipped. |
| Imported Submissions | Post nothing. |
| A post Slack refuses | Shown under Last post with Slack's error. It is not tried again. |
When it fails
| Slack says | What to do |
|---|---|
| That is not a Slack incoming webhook URL | Copy the hooks.slack.com/services/… URL from Incoming Webhooks. Workflow Builder URLs (/triggers/…) are not supported yet. |
no_service, no_active_hooks, invalid_token | The webhook was removed, or its app uninstalled. Add a new webhook and paste it. |
channel_not_found, channel_is_archived | The channel is gone or archived. Add a webhook for another channel. |
action_prohibited, posting_to_general_channel_denied | A Slack admin restricts who can post there. Pick another channel, or ask them. |
A bot that reads the channel, such as your own AI assistant, must be set to accept messages
from apps: many ignore bot_message and bot_id by default. Every message carries the
Submission's id, to quote back.
Plans
Each Integration names the plan feature that includes it. The check runs every time a hook runs, not only when the Integration is switched on. A Workspace that loses a feature stops running it, even if the Form's toggle is still on. Today every Workspace includes everything.
What did you think of this content?
Field types
A Field has a key, a label, a type and required. Scale, satisfaction and choice carry a little more; a rule can show a Field only when an earlier one matches.
Webhooks
One signed POST per event. Three events: created (always), accepted (after the gate), and status_changed (when a person moves a Submission).