Webhook - Enhanced with dynamic elements in path RESTful API approach [GOT CREATED]

I find myself using some 3rd party APIs that require to include dynamic elements into the URL. (i.e. /api/customer/{{id}}/update)

The same way, I really need to be able to create a webhook that can receive dynamic elements in the URL or even additional paths than the one set in the webhook. (defined by other systems in this way). (i.e this setup in n8n as the path: /webhook/invoice) and be able to receive posts to /webhook/invoice/{{id}}/delete or /webhook/invoice/{{id}}/update.

Maybe even a wildcard such as the ? works for query params that receives the post and brings the query param into the response. i.e /webhook/invoice?account=apj results in including this into the response: query: {“account”: “apl”}. This way anything after an ending “/” of the webhook could come to the response as additionalPath: “{{id}}/delete” or whatever comes after the defined webhook.

I really need this to go forward with a project, any ideas for a way around this would be awesome!

I think this can be a gamechanger in terms of the power of webhooks!
If you think this can help your projects please help me upvote this FR :wink:

@jan @maxT @RicardoE105

Hey @pradilla!

Definitely see the value in a wildcard that then makes the rest of the URL available to the workflow. I imagine there are some complexities under the hood but would also allow to build out workflows that look and feel much more like RESTful endpoints (and so more usable with other systems). Have upvoted this.

Quick loom video on queries with Webhook - does that help for this immediate usecase? https://www.loom.com/share/8b9bc642e384412c9f712242dc8c23c7

Thanks!

1 Like

Excellent!!! Thanks for the UpVote! :wink:
Regarding the query. I actually am receiving parameters and even without them being configures in the webhook url n8n processes these correctly! :+1:

Wilcard URL Paths Rocks :metal:

1 Like

Just as a short update. We are currently working on the implementation of this feature.

2 Likes

This will beam the usage of the webhooks in google sheets up to the moon.
Making Post requests with google apps is much more complicated I think.

Looking forward.

1 Like

Welcome to the community @David!

The feature got yesterday merged and will be released with the next version. So not much longer. Is already available in the nightly docker build n8nio/n8n:nightly

You can find the PR here:


And a short video about the feature here:
6 Likes

Got released with [email protected]

2 Likes

This is awesome!!! @jan Tested, works just live video! :+1:
Now, one question. While running n8n cloud, I have a couple webhooks without the /{{webhookId}} in the url. This was one of the coolest features. When making any change to these webhooks it adds the {{webhookId}} so I will need to re-submit the endpoint to the 3rd party already running some workflows.

Is there any way to get rid of this {{webhookId}} in the URL as before?

Example below with 4 different incoming flows. Client create which does not have any {:id}, and then 3 more incoming commands that do have {:id} in the url regarding the specific customer id.

I only have to submit the initial part of the path to the 3rd party. i.e https://actx.app.n8n.cloud/webhook/c71871f3-d1f0-4912-bf94-4d41e54bfca4/actx/clients

I already have submitted this 2 months ago and they are running on this one: https://actx.app.n8n.cloud/webhook/actx/clients

So I would have to send them a change and it wont be ideal. :slightly_frowning_face:

Then on their side they just add the {{:id/ specific command }}. For this case I included /{id}/delete, /{id}/update, /{id}/invoice

https://actx.app.n8n.cloud/webhook/c71871f3-d1f0-4912-bf94-4d41e54bfca4/actx/clients/:clientId/update

https://actx.app.n8n.cloud/webhook/c71871f3-d1f0-4912-bf94-4d41e54bfca4/actx/clients/:clientId/delete

https://actx.app.n8n.cloud/webhook/c71871f3-d1f0-4912-bf94-4d41e54bfca4/actx/clients/:clientId/invoice

As you can see I had to manually include the {{webhookId}} in the path that does not contain {{:id}} in the url. vs the path in Update that does include an {{:id}} in the path.

Clients Webhook image

Update Webhook image

{
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "c71871f3-d1f0-4912-bf94-4d41e54bfca4/actx/clients",
        "responseMode": "lastNode",
        "options": {}
      },
      "name": "Clients",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        536,
        252
      ],
      "webhookId": "c71871f3-d1f0-4912-bf94-4d41e54bfca4",
      "color": "#F71963",
      "continueOnFail": true
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "actx/clients/:clientId/update",
        "responseMode": "lastNode",
        "options": {}
      },
      "name": "Update",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        536,
        392
      ],
      "webhookId": "c71871f3-d1f0-4912-bf94-4d41e54bfca4",
      "color": "#F71963",
      "continueOnFail": true
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "actx/clients/:clientId/delete",
        "responseMode": "lastNode",
        "options": {}
      },
      "name": "Delete",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        536,
        532
      ],
      "webhookId": "c71871f3-d1f0-4912-bf94-4d41e54bfca4",
      "color": "#F71963",
      "continueOnFail": true
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "actx/clients/:clientId/invoice",
        "responseMode": "lastNode",
        "options": {}
      },
      "name": "Invoice",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        536,
        672
      ],
      "webhookId": "c71871f3-d1f0-4912-bf94-4d41e54bfca4",
      "color": "#F71963",
      "continueOnFail": true
    }
  ],
  "connections": {}
}

@maxT @Ben any suggestion on last question from @pradilla about paths?

Thanks @pradilla and @JOSE_ALEJANDRO_DIAZ for the feedback!

TL;DR: if you want to use parameters in your route there is unfortunately no way around the usage of the {{webhookId}} as a prefix in the URL at the moment.


We thought a lot about possible solutions and their trade-offs, due to the many requirements such as scalability, reliability and flexibility. In the end we have to be able to identify what route we are receiving and how we need to parse it in order to pass the params with the right keys and values. We decided that prefixing the route with the webhookId would be the solution that provides the most flexibility and reliability with understanding that this solution might not be 100% optimal at times.

We will continue reiterating on this feature and improvements will be made in the future.

What could be added short-term is that the webhookId can also be transmitted via the body or the query in order to keep the route lean. Maybe this might be a solution for your cases?

Sorry for not having better news.

Cheers,
Ben

1 Like

@Ben, thanks for the reply and the great job with this feature! Adding {{webhookId}} to the body would not be a good thing because body usually comes in the way the 3rd party has defined the structure. (At least for our current use case)

Having the URL clean of long hashes was a nice thing, but I think it is really not a problem! We will send out our 3rd party the new URL structure including the {{webhookId} and this should solve it. I created this test scenario (posted above) with 4 incoming hooks (1 static and 3 dynamic) so what I did was add the original {{webhookId}} to the path on the static route since my 3rd party will only receive 1 endpoint and use it for all the 4 purposes (the static one and the dynamic ones).

Will keep you posted when we have this workflow up and running in production mode :wink:

Kind Regards,
Andres

1 Like

@pradilla, awesome! Looking forward to hear what you have built and how it is running in production for you :+1:

as you have mentioned we wanted to keep the beauty of clean routes at least for static paths, however adding the {{webhookId}} to the static route(s) is what we recommend if you need to provide static as well as dynamic routes. So you are implementing it the same way as we would do it :+1:

Cheers,
Ben

1 Like