Shingle help
Send to other apps
Send each new submission to Zapier, Make or your own app.
Send submissions to another app
Each new submission from your published site can go to another app as it arrives, such as Zapier, Make or your CRM. You still get every submission in Forms, and by email if you've set that up.
- In the other app, make a webhook and copy its web address. In Zapier, start a Zap with Webhooks by Zapier and Catch Hook. In Make, start a scenario with Webhooks and Custom webhook.
- In your site's editor, open Forms. Under Send to other apps, choose Add web address.
- Paste the address and choose Add address.
- Choose Send test. The other app gets a test submission shaped like your site's form, so you can match its fields. The row then says whether it was delivered.
A site can send to up to five web addresses. Test messages you send from the editor's preview aren't sent to other apps: use Send test instead. To stop, choose Remove… beside the address.
To add a web address you need a member role or higher, and a confirmed email.
What each submission carries
Each submission is sent as JSON in a POST request:
{
"id": "sfs_01jbst2z2efcd9tbjzc2mb7h0m",
"type": "form.submitted",
"created_at": "2026-10-27T09:30:00.000Z",
"test": false,
"site": { "id": "site_01jbst2z2efcd9tbjzc2mb7h0n", "name": "Hill Plumbing" },
"form": { "key": "quote", "name": "Request a quote" },
"submission": {
"page_path": "/",
"fields": [
{
"key": "email",
"label": "Email",
"type": "email",
"value": "[email protected]"
},
{
"key": "updates",
"label": "Send me updates",
"type": "checkbox",
"value": true
}
],
"values": { "email": "[email protected]", "updates": true }
}
}
values has each answer by its field's key, which is the easiest to match in Zapier or Make. fields has the same answers with their labels, in the form's order. A checkbox's answer is true or false. A test has "test": true and made-up answers.
If a delivery fails
When the other app doesn't answer, or answers with an error, Shingle tries again a few times over the next few minutes. The address's row shows how the last delivery went, and what the app answered. A submission that couldn't be sent is still in Forms. To find out more about forms, see Forms and submissions.
Check that a submission came from Shingle
If you build your own app to receive submissions, check each request's signature. Every request has a Shingle-Signature header like t=1793000000,v1=5257a869…. Choose Copy secret to copy the address's signing secret.
- Join
t, a dot and the request's body exactly as it arrived:1793000000.{"id":…}. - Make an HMAC-SHA256 of that with the signing secret, written as hex.
- Compare it with
v1in constant time, and refuse atmore than five minutes old.
The Shingle-Delivery header stays the same each time a submission is tried again, so your app can skip one it already has.
Send what happens in your team to another app
A site's web address above gets that site's form submissions, with the answers. Your team can also tell another app what happens across all of its sites, as it happens. These are events, and they are set up once for the whole team.
- Open Settings, then Webhooks, and choose Add web address.
- Paste the address, and tick the events it should hear about.
- Choose Add address. Copy the signing secret then, because it is shown only once.
- Choose Send test on the address's row. The row then says whether it was delivered.
A team can send its events to up to ten web addresses. You need an admin role or higher, and a confirmed email. To stop, choose Remove… beside the address.
The events you can choose:
- A form was filled in (
form.submitted), A booking was made (booking.created), A new customer came in (customer.created), A customer replied (conversation.message_received) and A demo link was opened (pitch.opened). - A site went live (
site.published), A site was taken offline (site.unpublished), A build or a change finished (site.build_finished) and A build or a change failed (site.build_failed). - An agent asked for an OK (
agent_request.awaiting_ok), and what became of the request:agent_request.approved,agent_request.denied,agent_request.doneandagent_request.failed.
Each event is sent as JSON in a POST request:
{
"id": "tevt_01jbst2z2efcd9tbjzc2mb7h0p",
"type": "form.submitted",
"created_at": "2026-11-10T09:30:00.000Z",
"team": { "id": "ws_01jbst2z2efcd9tbjzc2mb7h0q" },
"site": { "id": "site_01jbst2z2efcd9tbjzc2mb7h0n" },
"data": {
"submission_id": "sfs_01jbst2z2efcd9tbjzc2mb7h0m",
"form_key": "quote"
}
}
An event says what happened and names the thing by its id. It holds a few short facts in data, and none of what anyone wrote: a form's answers and a customer's words stay in Shingle. To get a form's answers in another app as they arrive, use the site's own web address above. site is null for an event about the team itself. A test has the type webhook.test and an id that starts with test_.
Events are signed and tried again the same way as submissions, so the two sections above hold for them too. The Shingle-Delivery header carries the event's id.
An agent connected to your team can read the same events without a web address. To find out more, see Connect your own agent.