I noticed that Otto has new feature Table Triggers. What are the practical use cases for this?
You can send record updates to a webhook receiver. It’s like Window transaction, but works on the server. You can create audit logs or update records in another system.
Pretty sweet huh.
Strictly speaking this is an undocumented FIleMaker server 22.0.3 feature. It is what Studio uses.
We just expose a UI for it.
Todd
So it seems that only one file / table can be monitored?
One table can be monitored with one trigger, to monitor multiple files and tables you would need to make a trigger per table/file combination.
-Kyle
Ok I see now - however it would be nice for the interface to see at a glance all the files table triggers that are enabled. I can see how things could be set and forgotten not realizing a file has a trigger.
@OceanWest its in the release notes for FMS 22.0.4 rtfm
If you want a quick overview the FMDiSC from Dec 12th, near the end will help
This is an async process as Todd says that it triggered from a data change in a record, some ideas:
lightweight audit log
notifications when record has been added manually
this interface is an affordance, you can easily query the GetAll end point to see what triggers are on a file yourself, including status and any unresolved queue items
@john_r I’m set up a simple (?!) test
- used OttoFMS to set up a Trigger on a 3 field table
- the priv set used for the api key has access via fmottdata & create/edit/view/delete for the fields
- the webhook endpoint is going to another file using a webhook configured in Otto [the test in OttoFMS for this works as expected]
When changing data in my source table I’m not seeing any webhooks come through. So I used Postman to run a webhook.getall and the following response is returned:
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 16 Mar 2026 17:27:45 GMT
Content-Type: application/json;charset=utf-8
Content-Length: 624
Connection: close
OData-Version: 4.01
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Access-Control-Allow-Origin: impact.kizasolutions.com
Access-Control-Allow-Credentials: True
Access-Control-Allow-Headers: Content-Type,Authorization
{"@context": "https://impact.kizasolutions.com/fmi/odata/v4/rcc_data/$metadata#Webhook Processor","status": "ACTIVE","webhooks": [{"webhookID": 1,"tableName": "temp","webhook": "https://impact.kizasolutions.com/otto/receiver/API_integrations.fmp12/channel_testing?apiKey=MYKEY","headers": {},"notifySchemaChanges": false,"select": "\\\"webhookId\\\",\\\"buyOrderId\\\",\\\"lbsSold\\\"","filter": "ROWMODID > 0","pendingOperations": [{"operation": "UPDATE","rowIDs": [13],"status": "NOT_SENT","lastErrorCode": -1002,"lastErrorMessage": "Error: syntax error in URL at: '0'","sendAttempts": 165}]}]}
→ of course, as I re-run that call the pendingOperations keep incrementing… any advice on trouble shooting?
As a ‘just incase’ thing I escaped the three field names when configuring the webhook.
Thanks!
Colleen
@chammersely
easy one
the $filter should NOT use comparators like < or = , but lt, gt, eq
so your filter should be ROWMODID gt 0
your next step is to delete the web hook and make it again, as you can’t ‘edit’ one. so copy the bits you need into a txt doc and then paste in when you create a new one.