Webhook setup

Sends survey responses to your own address and checks that the receiver accepted them

Free agent skill for Claude Code, Codex, Cursor and Gemini CLI. It works through the SurveyNinja MCP server, with your permissions.

Category
Deliver responses
Tags
webhook, integrations
Works with
Claude Code, Codex, Cursor, Gemini CLI
MCP tools
9, 4 of them change data
Version
1.1, October 20, 2026
Made by
SurveyNinja
Price
Free
See also
Webhooks integrationZapier integration
Skill file
SKILL.md

What it does

  • Responses go straight into your system. Every response is sent as an HTTP request to your address, with the fields you need under the names you need.
  • Delivery is checked. After the first response the skill reads the delivery log: the receiver's status code and reply.
  • Access keys stay out of the chat. Keys for your receiver go into the webhook headers in the app. You never dictate them to the assistant.

Example

You type

Set up a webhook to send responses to our server

What the assistant brings back

3
Fieldsof nine questions
no
Unfinished
47
Deliveriesthis week
0
Errors
  1. https://crm.example.com/hooks/survey post, finished responses, switched on
  2. phone ← Your phone field renamed
  3. rating ← How happy are you? field renamed
  4. Authorization: *** header, value hidden
  5. Last delivery 30 September 14:02, receiver answered 200
The receiver accepted the first response with code 200

The webhook works. If the receiver starts answering 4xx, the assistant will not resend blindly. The cause gets fixed first, and the resend comes after.

The address and fields above are an example. The setup is built for your system.

How it works

  1. Looks at what is already set upA second webhook to the same address is almost always a mistake. The assistant checks the list before creating anything.
  2. Asks the four things nothing works withoutThe address, the method, which fields to send and what to call them. Field names match your system through renaming.
  3. Careful with incomplete responsesIf you want incomplete responses too, they go out with a delay. Otherwise a person who comes back to finish arrives twice.
  4. Reads the delivery log200 means it works, 4xx means the receiver rejected the request, 5xx is an error on their side. Nothing is resent while the receiver keeps failing.

Try also

  • Send the phone from the survey to our CRM as a field called phone
  • Check whether responses are arriving through the webhook

What it will not do

  • Do not create a second webhook to the same address
  • Do not send every question
  • Do not ask the person to dictate access keys into the chat
  • Do not enable a webhook that was disabled on purpose
  • Do not suggest a plan upgrade or lead to payment

The skill works with your permissions. Tools that change data are marked, so you check what the assistant is about to do before you confirm. To cut access, remove the connector in the assistant or delete the API key.

In short

Are webhooks available on my plan?

The skill checks this first, because webhooks are not on every plan. If they are not available, it tells you right away and stops.

What do I need to tell it, and who creates the webhook?

Four things: the address (a public http or https one), the method (almost always POST), which fields to send and what your system calls them. Connected by API key, the assistant creates the webhook. In Claude, ChatGPT and other assistant apps connected with Allow access, you create it in the app from the values the skill prepares, and the skill takes it from there.

Can fields be named the way my system expects?

Yes. If your system expects phone and the question is called Your phone, the skill renames the field in the payload. The question in the survey stays as it is.

Will incomplete responses be sent?

By default only finished ones are sent. If you want abandoned ones too, the skill sends them with a delay of 1, 6, 12 or 24 hours, so a person who comes back to finish does not arrive twice.

How do I know the webhook works?

A new webhook starts switched off, and the skill turns it on when you confirm the receiver is ready. After the first response it reads the delivery log: 200 means it works, 4xx means the receiver rejected the request, 5xx is an error on their side. An empty log means there were no responses yet.

How do I pass an access key for my system?

Do not paste it into the chat. Put keys into the webhook headers in the app. The assistant only sees header values hidden behind asterisks.

The full skill

The SKILL.md file the assistant reads, exactly as it is in the archive.

Show the full text

Webhook: responses to your own address

A webhook is the most direct way to get responses into your own system: every response goes out as an HTTP request to the given address. It is quick to set up and quiet when it breaks, so order matters more than speed here.

Reply to the person in the language they write in.

1. Check that webhooks are available

get_workspace_tariff (the workspace_id comes from get_workspace_list): webhooks are not part of every plan. If they are not available, say so right away and stop. Creating and switching on a webhook check the plan too, but collecting the address, method, fields and headers only to hit a refusal at the last step wastes the conversation.

If the target is Zapier, a webhook is not needed: SurveyNinja has a Zapier integration. The zap is built in Zapier, and manage_quiz_zapier shows whether sending is on and switches it.

2. See what already exists

get_quiz_webhooks lists the survey's webhooks, whether each is on, and whether one switched itself off after a run of failed deliveries. A second webhook to the same address is almost always a mistake, not a wish: check before creating.

3. Find out four things

Nothing can be created without them:

What Why
Address where to send; a public http or https address (internal addresses are rejected), and the receiver must answer 2xx
Method post almost always; get, put, patch if the receiver demands it
Which fields a contact and two or three key answers beat the whole questionnaire and are easier for the receiver
Field names if the system expects phone and the question is "Your phone", rename it with body_naming

Question names and identifiers come from get_quiz_structure.

4. Create and switch on

Who creates the webhook depends on how the assistant is connected. A webhook sends every response to an outside address, so on an "Allow access" connection (the sign-in Claude, ChatGPT and other assistant apps use) the server does not offer create_quiz_webhook and update_quiz_webhook: text inside a respondent's answer must not be able to send everyone's responses elsewhere. If these tools are not in your list, that is the reason. Do not look for a way around it.

Connected by API key: create_quiz_webhook with a title (for the person, to tell webhooks apart), address, method, fields (body), renaming (body_naming) and headers (headers, where the receiver's access keys go).

Connected with "Allow access": the person creates it in the app, and you give them the values from step 3 ready to enter. Open the survey, the Integrations tab, Webhook, then Create a Webhook. Name of the Webhook is the title, Call Back URL the address, Request Type the method. Custom Header holds the receiver's keys, which the person types in themselves. In Elements every question is selected; a click leaves one out. Parameter names renames the fields. Then Save. get_quiz_webhooks shows the new webhook, and from here the two ways are the same.

Unfinished responses: incomplete and hours, or Send incomplete responses and Send every in the app. By default only finished ones are sent. If abandoned ones are wanted too, send them with a delay of 1, 6, 12 or 24 hours; otherwise a person who comes back to finish arrives twice.

A new webhook is created switched off. Tell the person, and once they confirm the receiver is ready, turn it on with toggle_quiz_webhook.

5. Verify delivery

After the first response, read get_quiz_webhook_logs: the receiver's response code and body. 200 means it works. 4xx means the receiver rejected it, usually because of the address, the method or the body format. 5xx is an error on their side. An empty log means no responses yet, which is not an error.

Do not resend with resend_quiz_webhook_log while the receiver answers with an error: the same thing will happen again. Once it is fixed, resend one entry by log_id or every entry over a period.

Change, disable, delete

  • Fix the address or fields with update_quiz_webhook. Fields you do not pass keep their values, so send only what changes. headers is replaced as a whole list, and header values come back masked: to change one header, ask the person for the others again, or leave headers out entirely. On "Allow access" the person changes it in the app: Edit in the menu next to the webhook in the Webhooks list.
  • A webhook that switched itself off after failures comes back on with toggle_quiz_webhook, once the receiver is fixed.
  • To pause while they fix their side, switch it off with toggle_quiz_webhook rather than deleting it.
  • Delete with delete_quiz_webhook only on a direct request: the settings, headers and delivery log are gone for good.

What not to do

  • Do not create a second webhook to the same address without asking.
  • Do not send every question when there are many. The receiver needs the right fields.
  • Do not ask the person to dictate access keys into the chat. Ask them to put the keys into the webhook headers in the app, or insert only what they sent themselves.
  • Do not enable a webhook that was disabled on purpose.
  • Do not suggest a plan upgrade or lead to payment. If a limit is hit, state the fact and stop.
The SurveyNinja ninja on a rocket

Connect SurveyNinja to your assistant

The MCP server works on every plan, Free included. Sign up, allow access and ask your assistant to build the first survey.