Silverfin supports a range of webhook events which allow you to track changes in your environment, and can function as a trigger for your own API flows based on such an event.
Currently the API supports the following webhook events:
Event | Description |
---|---|
account.created | an account has been created |
account.updated | an account has been updated |
account.destroyed | an account has been deleted |
transaction_document.processed | a document is processed attached to a booking (coming from the accountancy system) |
permanent_document.processed | a document is processed uploaded in the Silverfin documents section |
comment.created | a new comment is created (currently limited to remarks only, but will be extended to checks as well) |
comment.updated | a new comment has been updated |
comment.destroyed | a comment has been deleted |
remark.created | a new remark is created (can be on any object within Silverfin: company, reconciliation, report, ...) |
remark.updated | a remark has been updated |
remark.destroyed | a remark has been deleted |
custom.updated | when a custom property on a company is created or updated |
period.created | when a period is unarchived |
period.updated | when a period is changed from private to public or from public to private |
period.destroyed | when a period is archived |
sync_state.updated | when a data synchronisation completes or fails, the payload contains if the sync has changed anything |
financial_balances.changed | when there are changes to financial data that might change the trial balances |
export.created | when a new export PDF is generated |
export.destroyed | when an export has been deleted |
The endpoint will send a POST request with a JSON payload to a specified target URL
. It will always include the webhook
, event
, and company
sections. The document section mentioned in the example below is specific to events related to documents.
{"webhook":
{
"id": 1052767521,
"url": "http://localhost:3001/webhook",
"events": ["transaction_document.processed", "permanent_document.processed"]
},
"event": "permanent_document.processed",
"company":
{
"id": 398393022,
"name": "Demo Company"
},
"document":
{
"id": 147764866,
"file_name": "permanent_test_file.docx",
"content": "This is the content of the file",
"download_url": "https://live.getsilverfin.com/url_of_the_actual_file",
"permanent_document_path": ["Contract", "A private document"],
"permanent_document_id": 411704894
}
}
Webhook signature verification
Every request must include two signature headers: X-SF-SIGNATURE-1
and X-SF-SIGNATURE-2
. These signatures are generated using your application's webhook_signing_token_1 and webhook_signing_token_2, respectively.
To confirm the authenticity of a request originating from Silverfin, you should compute its Hash-based Message Authentication Code (HMAC) using the SHA-256 digest algorithm, the request's body as data, and a webhook signing token as the key. For instance, in Ruby, you can achieve this as shown below:
OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), WEBHOOK_SIGNING_TOKEN, REQUEST_BODY)
If at least one of the computed signatures matches its respective header, you can consider the request as authentic. Matching with a single signature allows for a seamless rotation of your application's webhook signing tokens.
Retry strategy
When the endpoint doesn't reply with a 2xx
code, the post will be retried with an exponential back-off over a total duration of ~48 hours. If after this time the endpoint still doesn't reply with a 2xx code
, the webhook subscription will be marked as expired (disabled). Also note that an expired webhook subscription can't be revived, only deleted. To restore its functionality, the subscription will need to be re-created anew.
Throttling
Silverfin does not throttle outbound webhook events. To protect your application from occasional spikes in incoming events, you may wish to build your own solution or use a third-party service.
Timeouts
Silverfin requires the webhook receiving server to reply within a reasonable time. If the server takes too long to respond, the webhook event will be failed and be retried according to the Retry strategy described above. To avoid timeouts, you should defer processing of the payload until the server replies