Centralized_Reporting_Backend/docs/N8N_WEBHOOK_FORMAT.md
2025-10-10 12:10:33 +05:30

6.6 KiB

n8n Webhook Request Format

How Data is Sent to n8n

Backend Request Format

Our backend sends data like this:

// 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:

{
  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)

$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)

$json.body.acces_token  // "1000.xxxxx" or "00DdN00000ne1xG!..."

Instance URL (for Salesforce)

$json.body.instance_url  // "https://yourinstance.salesforce.com"

Query Parameters (for pagination/filters)

$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:

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:

// 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:

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:

// 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

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

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

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:

// 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:

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:

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:

// 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