Can’t return validationToken from Webhook (GET) to validate Microsoft Graph subscription

Hi everyone,
I’ve been trying to set up a webhook in n8n to validate a Microsoft Graph subscription. As per the docs, Microsoft sends a GET request with a validationToken query parameter and expects a plain text response with a 200 OK.

Example request:

GET https://<my-url>?validationToken=1234

Expected response:

  • Status: 200
  • Content-Type: text/plain
  • Body: 1234

I’ve tried:

  • Webhook with Respond Immediately, and using:
    {{ $json.query.validationToken }} or {{ $request.query["validationToken"] }}
    → None of them work — either returns undefined, or error: No input connected.
  • Switching to Respond When Last Node Finishes, connecting a Code node with:
const token = $input.first().query?.validationToken;
return [
  {
    json: {},
    headers: { 'Content-Type': 'text/plain' },
    body: token,
    statusCode: 200
  }
];

→ Still doesn’t work. query is always empty or missing.


Important: I’ve dumped the full input using a Code node and confirmed that validationToken is present under item.query.validationToken. But I still can’t build a flow that returns it correctly as plain text with a 200 response.


Has anyone here successfully validated a Microsoft Graph subscription from n8n?
What’s the cleanest way to return a validationToken in plain text from a GET request?

Thanks in advance :folded_hands:

{
“nodes”: [
{
“parameters”: {
“path”: “sharepoint-dump”,
“responseCode”: “={{ 200 }}”,
“options”: {
“responseData”: “={{ $json["query"]["validationToken"] || "No validationToken received" }}”
}
},
“id”: “22945030-90ec-497a-b3e7-24ec737b3a4a”,
“name”: “Webhook (GET)”,
“type”: “n8n-nodes-base.webhook”,
“typeVersion”: 1,
“position”: [
500,
200
],
“webhookId”: “efb95fd7-6ca6-4c43-9acc-e0d1d4ba6611”
},
{
“parameters”: {},
“id”: “41975f5f-186f-4811-afa9-39b51907614c”,
“name”: “Code”,
“type”: “n8n-nodes-base.code”,
“typeVersion”: 1,
“position”: [
700,
200
]
}
],
“connections”: {
“Webhook (GET)”: {
“main”: [
[
{
“node”: “Code”,
“type”: “main”,
“index”: 0
}
]
]
}
},
“pinData”: {},
“meta”: {
“instanceId”: “cd5be015c0399c2c97daa3c1dc0d861cdb61c89c464a803a99188a92d5ff598c”
}
}

In the following workflow you can see a “Webhook” node, configured to reply from “Respond to Webhook” node connected to the “Respond to Webhook” node, configured with a text response, which includes a part of the request qs.

Would this do?

2 Likes

Thank you! It is the first time I’m using n8n and there are some things that I need to understand better, but with your help I could make this work.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.