Utilising API/Webhooks

I’m using the GRIST API extensively and it works well, no problems creating/updating tables etc. I’d, however, love to be able to trigger a webhook from Grist. Being able to notify other apps through a Webhook when a particular field is updated would be amazing. Is there anything is the works for this?

Yes, Grist has webhooks! They’re just not really documented. You can learn how to set up a webhook manually here: Support outgoing webhooks · Issue #76 · gristlabs/grist-core · GitHub

You can also use an integrator: Integrator Services - Grist Help Center

Zapier and Pabbly use webhooks for their instant triggers. Integrately also supports Grist triggers, but not by using webhooks.


Thank you for the feedback! I’m not sure I understand the process. After reading through the GitHub info, it mentions that for Hosted Grist, which I assume I’m using (not self-hosted) that I need to request the Grist staff to add the domain I intend to send the Grist Webhook data to. I’m using Meta-API (https://www.meta-api.io/) as they just added the Grist API after I requested it. I’d appreciate any other info you can provide to help me in figure it out.

Hi @Leon, we’ve put meta-api on the allowed list of webhook targets for our hosted service. The change will take effect on Sunday, and should be available for use on Monday.


Hi Guys,

I have gone through the example on Github Support outgoing webhooks · Issue #76 · gristlabs/grist-core · GitHub -

“Make a practice Grist document that has a table called Stuff , a text column called Name , and a toggle column called Ready . Make a few rows. Make sure all Ready cells are unset/blank/off - it will represent whether a row is available for sending to the webhook.”

I can add/remove via API to it, no problem. As mentioned in the example, I can also subscribe a Webhook and get results with an unsubscribe key etc. I can also unsubscribe the Webhook.

The issue is that when I continue with the example and toggle the “Ready” cell and change the “Stuff” cell, I seems that I get no webhook sent. I tried with Webhook.site and with Meta API webhooks.

It there anything I can do to check if the Webhook subscribed is actually working, or is there any other tip you can give to troubleshoot?

Thank you!

It sounds like you’re doing the right things. Webhook.site is a good place to start testing. Just in case, here are some things to double check:

  • The table you subscribed to is the same as the table you’re changing.
  • You subscribed again after making sure unsubscribe worked.
  • You made changes after setting Ready in the same row to on/true/checked.

To make the webhook as broad/general as possible to increase your chances of seeing something, set eventTypes to ["add", "update"] when subscribing and leave out isReadyColumn completely so that webhooks are triggered for all events.

Finally, if you add this formula to your table:

[(r.tableRef.tableId, r.eventTypes, r.isReadyColRef.colId, r.actions)
 for r in _grist_Triggers.all]

that will show the internally stored configuration which may be helpful.

Thank you for the feedback.

The first pic shows the subscribe cURL and the reply with the Webhook ID.

It matches the GRIST Webhook ID in the second pic from the formula you provided.

The third pic shows that the table name is “Stuff”.

Is there something else I’m missing?

No, it looks like you did everything perfectly. Thanks for the screenshots, this will let us search the logs for possible issues.

update I created an entirely new document and duplicated everything. The new document’s table is working with the “webhook.site” webhook. I’m not sure if you did something on your end, or if the new document did it. I’m going to try it with my webhook and see how it goes. Thank you for your awesome support!

Thanks for your help and patience. We looked at the logs and found that webhook.site was responding with 401 (Unauthorized) to the requests. This is very surprising, I have no idea why it would do that. You didn’t set up any passwords or anything special, right? I opened your webhook and was able to make two simple requests which went through fine, you should be able to see them. After that I saw requests coming through from Grist. Making a new document shouldn’t have made a difference, especially since the problem is webhook.site responding with 401 to the requests, and it doesn’t know anything about which document the requests come from!

1 Like

OK, we looked at the logs some more and found that the 401 responses were only coming from meta-api.io. Nothing was wrong with the webhook.site webhook. But Grist tries to send out webhooks in the order that the events were generated, so it was trying to get the meta-api events through first. And when a request fails, it tries it again several times before giving up. It did eventually, and you can see a big batch of events came through to webhook.site in one go after that.

Check the meta-api.io docs, maybe there’s an authentication header or something that needs to be included?

Thank you for the reply! I’ll follow up on your suggestions.

Regarding authorization, as seen below, is it correct to add the “?apikey” at end of the webhook url?

curl -H "Authorization: Bearer 9b875cxxxxxxxxxxxxxxxxb0a191a47" -H "Content-Type: application/json" \
  https://docs.getgrist.com/api/docs/sB73Lxxxxxxxxxxxxxxx9h9/tables/Stuff/_subscribe \
  -XPOST \
  -d '{"eventTypes": ["add", "update"], "url": "https://api.meta-api.io/api/spells/627axxxxxxxxxxxxxxx7e5/runSync?apikey=cd0f0xxxxxxxxxxxxxxxxxxx27d5e4f59ba3"}'

That looks correct based on Use a Spell in production | Meta API - Docs

1 Like

Did you get it working?

Yes, I got it all working. Now when particular fields are changed in the Grist document, my Meta-API Spell is notified via webhook and a customized message is sent to my Discord channel via a bot which depends on the change in my Grist document. I’m currently building the following workflow.

Example :
New member added to my Grist CRM => Discord “A new member called ‘NAME’ has been added to the CRM”.
A member status changed on my Grist CRM => Discord “‘Name’ status has changed to ‘status’” -

Pretty nice and very useful :slight_smile: Thank you for your help!

Awesome! Any other tips for future Meta API users apart from setting ?apikey?

I would say, don’t even try it if you are not familiar with running cURL commands or understanding what json data is and how to manipulate it with Javascript, you need to get your hands dirty with code, there is no drag and drop here - always make a note of the unsubscibe key, I needed it multiple times during testing. A step by step procedure would be a real help in that situation, however, once the webhook is working, the necessary Javascript knowledge is needed in Meta-API in order to manipulate the webhook data.

Regarding the connection between Grist and Meta-API, my main issue was that I did not realize that there were times where I had done the procedure correctly, but it still had not worked. The reason was that the initial incorrect testing was causing a timeout duration BEFORE the next webhook would arrive, therefore, I had not realized that it had worked and I would keep changing the code and causing a spiral of issues. It wasn’t until I created a new sheet with my different code, that I saw it working.

1 Like


Mathieu from Meta API. One of our users redirect me here.
I’ve created two Open Spells on our platform to help users to subscribe / unsubscribe a webhook. It’s working for any URL, so anyone could use it, even with a free account.
Subscribe a webhook: Meta-API - Dashboard
Unsubscribe a webhook : Meta-API - Dashboard

I also created a Spell, showing how we can push data from Grist to Airtable. That, of course, could be used for any others APIs (@Leon for trigger Discord for example).

@alexmojaki If I can help for anything to improve the use of Grist inside Meta API, I’ll be pleased to do it.


Hi Mathieu, thank you for the subscribe and unsubscribe spells! This will make a world of difference for those who need a simplified way to get webhooks up and running.