How to Send Typeform Responses to Slack
Post every new Typeform response to a Slack channel as a readable message (question, answer, respondent), verified with Typeform's webhook signature, and optionally summarised or routed by AI.
What This Integration Does
Typeform's own Slack integration posts responses, but you cannot control the format, route different answers to different channels, or add anything from another system. With a Spojit workflow you can. Typeform sends each response to a Spojit webhook the moment it is submitted; Spojit checks Typeform's signature so only genuine responses get through, pairs every answer with its question, and posts a clean message to Slack. Because it is a workflow, you can add steps: send sales enquiries to #sales and support requests to #support, ask AI to summarise a long answer, or look the respondent up in your CRM first.
Each submission produces one run and one Slack message. Typeform retries a webhook it could not deliver; the message is posted per delivery, so keep the response mode on Async so Spojit always acknowledges quickly and Typeform has no reason to retry.
Prerequisites
- A Typeform form you can edit (webhooks are under the form's Connect -> Webhooks tab).
- A Slack connection in Spojit with permission to post (
chat:write), and the Spojit app invited to the target channels. You need the channel ID (right-click the channel, View channel details; it starts withC).
Step 1: Webhook Trigger with Typeform Signing
Add a Trigger node with type Webhook. Next to Signing connection, click + and pick Custom:
- Signature header name:
Typeform-Signature - Algorithm:
SHA-256 - Encoding:
base64 - Value prefix:
sha256= - Signed payload:
Raw body
Enter a long random secret and save, then copy the webhook URL.
Step 2: Add the Webhook in Typeform
In Typeform, open the form, go to Connect -> Webhooks, click Add a webhook and paste the Spojit URL. Open the webhook's settings and set its Secret to the same value as in Step 1; without a secret Typeform does not sign requests and Spojit rejects them. Turn the webhook on, then use View deliveries later to see what Typeform sent.
Step 3: Pair Questions with Answers
The response arrives as {{ input.form_response }}. It contains definition.fields (each question's id and title) and answers (each answer's field.id, its type, and the value in a property named after the type: text, email, number, boolean, date, choice.label or choices.labels). Add a Code Runner step with execute-javascript and input {{ input.form_response }}:
const titles = Object.fromEntries(data.definition.fields.map(f => [f.id, f.title]));
const value = a => a.choice?.label ?? a.choices?.labels?.join(', ') ?? a[a.type] ?? '';
const lines = data.answers.map(a => `*${titles[a.field.id] ?? a.field.ref}*\n${value(a)}`);
return { text: lines.join('\n\n'), submitted: data.submitted_at };
Name the output formatted; the message text is in {{ formatted.result.text }}.
Step 4: Post to Slack
Add a Slack step with send-message:
channel: your channel ID.text:New response to {{ input.form_response.definition.title }}:\n\n{{ formatted.result.text }}unfurl_links:false, so links in answers do not expand into large previews.
For a richer layout, pass Slack Block Kit sections in blocks (keep text as the fallback shown in notifications).
Step 5: Route by Answer (Optional)
Add a Condition before Step 4 on a key answer, for example the "What can we help with?" choice, and use a separate Slack step per branch with a different channel. For free-text forms, an Agent Mode step with a Response Schema ({ "team": "sales" | "support" | "other", "summary": "..." }) classifies the response and writes a one-line summary to post above the full answers.
Tips
- Use field refs: give important questions a reference in Typeform's question settings (for example
budget). Refs stay the same when you reword the question, so Conditions keep working. - Hidden fields: values passed in the form URL (campaign, customer ID) arrive in
{{ input.form_response.hidden }}. Add them to the message for context. - Thread long answers: post a short summary to the channel and the full response as a thread reply using
thread_tsfrom the first message's output. - Keep a copy: add a MySQL or Monday.com step to store responses as well, so Slack is not your only record.
Common Pitfalls
- No secret, no signature: Typeform only sends
Typeform-Signaturewhen the webhook has a secret. Unsigned deliveries are rejected by Spojit. - Prefix and encoding: Typeform's signature is Base64 with a
sha256=prefix. Hex encoding or a missing prefix in the signing connection makes every delivery fail verification. - Bot not in the channel: Slack returns
not_in_channeluntil the Spojit app is added to the channel. - Personal data in Slack: forms often collect emails and phone numbers. Post only what the channel needs and keep sensitive answers out of public channels.
Testing
Submit the form yourself with test answers. Check the Spojit run history for the run, then the Slack channel for the message. If no run appears, open View deliveries on the Typeform webhook: a 401 means a signature mismatch, so re-check the secret, prefix and encoding.