Webhook body fields not passed to Google Calendar despite visible data

Summary:
I’ve created a workflow on Railway-hosted n8n to receive calendar appointments via a webhook and create them in Google Calendar. The webhook correctly receives JSON with title, start, and end fields — I can see them in the execution output.
But when I try to use {{ $json.title }} and similar expressions in the Google Calendar node, it shows up as undefined, and the events are created without title or time. I’ve tried all the tricks (Set node, Edit Fields, Code node) and nothing fixes it.


Details:
I’m using n8n hosted on Railway.app with the following workflow:

  • Webhook (POST) receives data like:

json

CopyEdit

{
  "title": "Dentist Appointment",
  "start": "2025-04-27T09:00:00Z",
  "end": "2025-04-27T10:00:00Z"
}
  • Execution Output clearly shows the data under body.title, body.start, and body.end.
  • Google Calendar node is using expressions like:

javascript

CopyEdit

{{ $json.start }}
{{ $json.end }}
{{ $json.title }}

…but they all return undefined in the node and the calendar event has no data.

  • What I’ve tried:
    • Adding a Set node to pass fields forward (didn’t work)
    • Using a Code node to map item.json = item.json.body; (no change)
    • Using an Edit Fields node to manually remap (still undefined)
    • Checked node execution order — webhook is triggering properly
    • Checked that I’m not missing Include Other Input Fields (it’s on)

I’ve also tried to use {{ $json.body.title }} instead of {{ $json.title }} but it also didn’t work. The Webhook does pull the data, but it seems to get lost before it gets to the google calendar node. The result is it creates a calendar appointment, but with no title, and the start and end dates/times are the exact current time that it is at the moment.

Goal:
Just want to reliably pass the webhook POST body values (title, start, end) into the Google Calendar node so they create a proper event.


Screenshots attached:



Thanks in advance — any help would save my sanity!

Hi @kross-uk Welcome to n8n :n8n: community :tada:

You’re very close!

The issue is that the title, start, and end fields are not at the root of the incoming JSON, they are nested under body

To access them correctly, you should use expressions like:

{{ $json.body.title }}
{{ $json.body.start }}
{{ $json.body.end }}

Alternatively, you can insert a Set node right after the Webhook to restructure the data and move body.title, body.start, and body.end to the root, making your original expressions work as intended.

Let me know if you need more help.

Hi, that was really clear, thank you. I’ve tried this but sadly it doesn’t work. After a bit of digging, I found that when I test the workflow using the test URL, it works correctly. N8N receives the data and ends the testing. The data goes through from the webhook into the google calendar node, and into my google calendar with correct title, start, and end dates.
However, running the same workflow on the production URL, N8N receives the data, but doesn’t end the testing. The webhook does receive the data, but it’s not passed on to the google calendar node. The appointment is created on my google calendar, but without any title, and the start and end dates will be whatever the time is at the time.

What could be causing this?

@kross-uk can you please replace these and tell me what you get?

Hi Mohamed, thanks for your reply. I have tried using $json.body.start, but it also doesn’t work. I’ve tried replicating the same exact workflow on a n8n hosted by n8n itself and it worked 100%. I think it’s because the instance I’m using is hosted on Railway. I’ve been doing a bit of digging and it seems like other people are having the same issues.

Got it, the issue seems to be with Railway and the production webhook URL…

Are you sure the webhook URL is set correctly?