Working with web hooks
What is a web hook?
A web hook is an event notification that you can set up such that when certain events happen in e-conomic, an external system will be automatically notified. Technically, this means that when a resource, e.g. an invoice or a product, is changed we invoke an HTTP POST request to the URL defined in the web hook setup.
Web hooks can, amongst other things, be used to trigger object synchronization between e-conomic and external systems, thus saving the external solution from having to constantly poll for changes in e-conomic data.
Setting up web hooks in e-conomic must be done by the accounting SuperUser by going to All settings -> Extensions -> Web hooks.
Important note!
Consuming web hooks requires you to be able to handle queueing of incoming events as these may come in large numbers in rapid succession. Any business logic that needs be performed based on web hooks should be run separately without locking the HTTP processes to ensure that you can still respond to web hooks.
We offer a guide on setting up a web hook consumer service here: https://techtalk.e-conomic.com/setting-up-a-robust-webhook-consumer/
Web hook types
Below you can see the different web hooks available in e-conomic.
Each web hook supports a number of merge fields that you can choose to include in the http request invoked by the web hook. This way, you can set up e.g. an "Invoice booked" web hook URL to automatically include the invoice number.
Type | Merge fields* | Description |
Invoice booked | [INVOICENO]: Invoice no. | Posts the booked invoice number. Triggered when an invoice is booked. |
Day book booked | [DAYBOOKNO]: Day book no. [FROMSERIALNO]: From serial no. [TOSERIALNO]: To serial no. | Posts the day book number as well as the serial number span of the booked entries. Triggered when a day book is booked. |
Customer updated | [NEWNUMBER]: New number [OLDNUMBER]: Old number | Posts the new and the old number when a customer is changed. Triggered on creation, deletion, update (any property) or re-numbering of a customer. |
Product updated | [NEWNUMBER]: New number [OLDNUMBER]: Old number | Posts the new and the old number when a product is changed. Triggered on creation, deletion, update (any property) or re-numbering of a product. |
Project updated | [NEWNUMBER]: New number [OLDNUMBER]: Old number | Posts the new and the old number when a project is changed. Triggered on creation, deletion, update (any property) or re-numbering of a project. |
Product inventory updated | [NUMBER]: Product number | Posts the inventory product number. Triggered on changes to a product's inventory counters: "In stock", "On order", "Available" and "Ordered". |
Order updated | [NEWNUMBER]: New number [OLDNUMBER]: Old number | Posts the new and the old number when a order is changed. Triggered on creation, deletion, update (any property) or re-numbering of a order. |
Invoice updated | [NEWNUMBER]: New number [OLDNUMBER]: Old number | Posts the new and the old SOAP CurrentInvoiceHandle.Id (REST: soap.currentInvoiceHandle.id) when a draft invoice is changed. Triggered on creation, deletion, update (any property) or re-numbering of a draft invoice. |
Quote updated | [NEWNUMBER]: New number [OLDNUMBER]: Old number | Posts the new and the old number when a quote is changed. Triggered on creation, deletion, update (any property) or re-numbering of a quote. |
Employee updated | [NEWNUMBER]: New number [OLDNUMBER]: Old number | Posts the new and the old number when the entity is changed. Triggered on creation, deletion, update (any property) or re-numbering. |
Payment term updated | [NEWNUMBER]: New number [OLDNUMBER]: Old number | Posts the new and the old number when the entity is changed. Triggered on creation, deletion, update (any property) or re-numbering. |
Customer group updated | [NEWNUMBER]: New number [OLDNUMBER]: Old number | Posts the new and the old number when the entity is changed. Triggered on creation, deletion, update (any property) or re-numbering. |
Product group updated | [NEWNUMBER]: New number [OLDNUMBER]: Old number | Posts the new and the old number when the entity is changed. Triggered on creation, deletion, update (any property) or re-numbering. |
Supplier updated | [NEWNUMBER]: New number [OLDNUMBER]: Old number | Posts the new and the old number when the entity is changed. Triggered on creation, deletion, update (any property) or re-numbering. |
Supplier group updated | [NEWNUMBER]: New number [OLDNUMBER]: Old number | Posts the new and the old number when the entity is changed. Triggered on creation, deletion, update (any property) or re-numbering. |
Dimension | [NEWNUMBER]: New number [OLDNUMBER]: Old number | Posts the new and the old number when the entity is changed. Triggered on creation, deletion, update (any property) or re-numbering. |
Chart of accounts updated | [NEWNUMBER]: New number [OLDNUMBER]: Old number | Posts the new and the old number when the entity is changed. Triggered on creation, deletion, update (any property) or re-numbering. |
Customer delivery location updated | [NEWNUMBER]: New number [OLDNUMBER]: Old number | Posts the new and the old number when the entity is changed. Triggered on creation, deletion, update (any property) or re-numbering. |
Customer contact updated | [NEWNUMBER]: New number [OLDNUMBER]: Old number | Posts the new and the old number when the entity is changed. Triggered on creation, deletion, update (any property) or re-numbering. |
Unit updated | [NEWNUMBER]: New number [OLDNUMBER]: Old number | Posts the new and the old number when the entity is changed. Triggered on creation, deletion, update (any property) or re-numbering. |
VAT account updated | [NEWNUMBER]: New number [OLDNUMBER]: Old number | Posts the new and the old number when the entity is changed. Triggered on creation, deletion, update (any property) or re-numbering. |
For the web hooks types containing NEWNUMBER and OLDNUMBER merge fields, i.e., "Customer updated", "Product updated", "Project updated", "Order updated" and "Invoice updated", the following logic applies:
If OLDNUMBER is blank, NEWNUMBER is the number of a created entity
If NEWNUMBER is blank, OLDNUMBER is the number of a deleted entity
If OLDNUMBER is identical to NEWNUMBER, the properties of the entity have been updated
If OLDNUMBER is different from NEWNUMBER, the entity has been re-numbered, and its properties mayalso have been updated
Note that the defined merge fields are always included, but will be blank if they don't contain any data.
Using web hooks
In the example below, the data is included in the query string and the 'Data posted' text area is left empty. Anything you set in the "Data posted" field goes in the body of the POST request.
Example: A "Product updated" web hook on product no. 33 is triggered by an update to the product description.
Web hook definition URL: http://www.domain.tld/webhookservice.aspx?newnumber=[NEWNUMBER]&oldnumber=[OLDNUMBER]
Result: http://www.domain.tld/webhookservice.aspx?newnumber=33&oldnumber=33
You may supply web hook setup instructions to your users as simply a Type and URL pair.
Example: "Navigate to the Web hooks menu by pressing period (.) to enter the QuickSearch popup. Type 'Web hooks' in the search field and click the link in the Extensions section. Click the 'New web hook' button. Create a new 'Product updated' web hook, paste the following into the URL field and then click OK: http://www.domain.tld/webhookservice.aspx?newnumber=[NEWNUMBER]&oldnumber=[OLDNUMBER]"
Requests and retries
e-conomic web hooks are not guaranteed to fire instantly, but in most cases they will. Bulk modification of data results in as many triggers of web hook requests to your server as the number of resources you have changed. The web hook requests are not bundled in one call even if they originate from a single API request.
Tip: Instant calls could potentially mean tens if not hundreds of requests to your server within seconds. As such it is recommended that you add these events to a local queue and defer your actions so you don't miss any web hook requests.
If a request to a web hook URL fails, the request will be retried up to 5 times. A failure is either a connection error to the server or a status code that is not in the 2xx range of status codes. The table below shows our retry policy:
Retry no. | Time since last failure |
1 | 1 second |
2 | 20 seconds |
3 | 1 minute |
4 | 5 minutes |
5 | 20 minutes |
- | Logged as failed |
After the fifth retry, no more retries are attempted.
If more than 250 requests to a specific web hook URL have failed in the last 24 hours, the web hook will be disabled and no more requests will be fired. We will not queue requests while the web hook is disabled, so all events are lost until you enable the web hook again.
Can I rely on web hooks alone?
As with any asynchronous web communication, there are many moving parts that can fail. So if you rely on web hooks alone, you run the risk of slowly getting out of sync if one or more web hooks fail to be sent, picked up or for some other reason just never makes it to your server.
To ensure consistency across systems, a nightly sync job will make sure that any missed web hooks are caught. Giving your customers a way to manually fire this sync is also a good idea. Before you implement a sync job we recommend that you read more in this blog post.
Need help?
We are ready to help you with your API questions at api@e-conomic.com.
And if you have questions regarding apps, don't hesitate to contact apps@e-conomic.com.