# n8n Webhook Request Format ## How Data is Sent to n8n ### Backend Request Format Our backend sends data like this: ```javascript // URL with query parameters const url = 'https://workflows.tech4bizsolutions.com/webhook-test/04e677f5-ec57-4772-bf12-96f2610d4b9c?per_page=100&page=1' // POST body sent directly (not wrapped) const body = { provider: "zoho", service: "crm", module: "leads", acces_token: "1000.xxxxx", instance_url: null } // Send to n8n axios.post(url, body, { headers: { 'Content-Type': 'application/json' } }) ``` ### What n8n Receives n8n automatically structures the incoming data as: ```javascript { body: { provider: "zoho", service: "crm", module: "leads", acces_token: "1000.xxxxx", instance_url: null }, query: { per_page: "100", page: "1" }, headers: { "content-type": "application/json" } } ``` ### How n8n Workflow Accesses Data #### Provider/Service/Module (for routing) ```javascript $json.body.provider // "zoho" or "salesforce" $json.body.service // "crm", "books", "people", "projects" $json.body.module // "leads", "contacts", "accounts", etc. ``` #### Access Token (for API calls) ```javascript $json.body.acces_token // "1000.xxxxx" or "00DdN00000ne1xG!..." ``` #### Instance URL (for Salesforce) ```javascript $json.body.instance_url // "https://yourinstance.salesforce.com" ``` #### Query Parameters (for pagination/filters) ```javascript $json.query // Full query object $json.query.per_page // "100" $json.query.page // "1" $json.query.instance_url // Also available here for Salesforce ``` --- ## Provider-Specific Examples ### Zoho Request #### Backend Sends: ```bash POST https://workflows.tech4bizsolutions.com/webhook-test/04e677f5-ec57-4772-bf12-96f2610d4b9c?per_page=200&page=1 Content-Type: application/json { "provider": "zoho", "service": "crm", "module": "leads", "acces_token": "1000.a1b2c3d4e5f6...", "instance_url": null } ``` #### n8n Workflow Uses: ```javascript // Switch routing $json.body.provider // "zoho" $json.body.service // "crm" $json.body.module // "leads" // HTTP Request to Zoho API URL: https://www.zohoapis.com/crm/v2/Leads Headers: Authorization: Zoho-oauthtoken {{ $json.body.acces_token }} Query: {{ $json.query.toJsonString() }} // {"per_page":"200","page":"1"} ``` ### Salesforce Request #### Backend Sends: ```bash POST https://workflows.tech4bizsolutions.com/webhook-test/04e677f5-ec57-4772-bf12-96f2610d4b9c?instance_url=https%3A%2F%2Fability-computing-5372.my.salesforce.com Content-Type: application/json { "provider": "salesforce", "service": "crm", "module": "leads", "acces_token": "00DdN00000ne1xG!AQEAQN0M3b...", "instance_url": "https://ability-computing-5372.my.salesforce.com" } ``` #### n8n Workflow Uses: ```javascript // Switch routing $json.body.provider // "salesforce" $json.body.service // "crm" $json.body.module // "leads" // HTTP Request to Salesforce API URL: {{ $json.query.instance_url }}/services/data/v59.0/query/?q=SELECT+Id,FirstName... Headers: Authorization: Bearer {{ $json.body.acces_token }} ``` --- ## Testing with cURL ### Test Zoho ```bash curl --location 'https://workflows.tech4bizsolutions.com/webhook-test/04e677f5-ec57-4772-bf12-96f2610d4b9c?per_page=100&page=1' \ --header 'Content-Type: application/json' \ --data '{ "provider": "zoho", "service": "crm", "module": "leads", "acces_token": "1000.your_zoho_token_here" }' ``` ### Test Salesforce ```bash curl --location 'https://workflows.tech4bizsolutions.com/webhook-test/04e677f5-ec57-4772-bf12-96f2610d4b9c?instance_url=https%3A%2F%2Fability-computing-5372.my.salesforce.com' \ --header 'Content-Type: application/json' \ --data '{ "provider": "salesforce", "service": "crm", "module": "leads", "acces_token": "00DdN00000ne1xG!your_sf_token_here" }' ``` --- ## Implementation in Backend ### src/integrations/n8n/client.js ```javascript async callWebhook(payload) { // 1. Build URL with query parameters const queryParams = new URLSearchParams(payload.query || {}).toString(); const url = `${this.baseUrl}/${this.webhookPath}/${this.webhookId}${queryParams ? '?' + queryParams : ''}`; // 2. Prepare POST body (sent directly, not wrapped) const requestBody = { provider: payload.provider, service: payload.service, module: payload.module, acces_token: payload.acces_token, instance_url: payload.instance_url || null }; // 3. Send to n8n const response = await axios.post(url, requestBody, { headers: { 'Content-Type': 'application/json' } }); return response.data; } ``` --- ## Key Points 1. **Direct POST Body**: We send the data object directly, not wrapped in another object 2. **Query Parameters in URL**: Pagination and other params go in the URL query string 3. **n8n Auto-wraps**: n8n automatically makes it available as `$json.body` and `$json.query` 4. **Same Format for All Providers**: Zoho, Salesforce, and others use the same structure --- ## Debugging ### View Raw Request in n8n In your n8n workflow, add a "Set" or "Edit Fields" node right after the webhook to see exactly what you're receiving: ```javascript // Add this as a Set node to debug { "received_body": "{{ $json.body }}", "received_query": "{{ $json.query }}", "provider": "{{ $json.body.provider }}", "service": "{{ $json.body.service }}", "module": "{{ $json.body.module }}", "has_token": "{{ $json.body.acces_token ? 'yes' : 'no' }}" } ``` ### Backend Logs Check backend logs for: ``` Calling n8n webhook: { url: '...', provider: 'zoho', service: 'crm', module: 'leads' } Sending to n8n: { url: '...', body: { provider: 'zoho', ... } } n8n webhook response received: { provider: 'zoho', status: 200 } ``` --- ## Common Issues ### Issue: "$json.body.provider is undefined" **Cause**: Data not being sent in POST body **Solution**: Ensure axios is sending the object directly: ```javascript axios.post(url, requestBody) // ✅ Correct // NOT axios.post(url, { body: requestBody }) // ❌ Wrong (double wrapping) ``` ### Issue: "$json.query is empty" **Cause**: Query parameters not in URL **Solution**: Append query params to URL: ```javascript const queryString = new URLSearchParams(payload.query).toString(); const url = `${baseUrl}?${queryString}`; // ✅ Correct ``` ### Issue: "Invalid token" **Cause**: Token not being passed correctly **Solution**: Verify token is in `$json.body.acces_token`: ```javascript // In n8n HTTP Request node Authorization: Zoho-oauthtoken {{ $json.body.acces_token }} // or Authorization: Bearer {{ $json.body.acces_token }} ``` --- **Last Updated**: October 9, 2025 **Version**: 1.0.0