POST request whenever one of the selected business events occurs.
In Fintoro API, webhooks are designed as a thin trigger, not as a parallel snapshot API. The delivery payload always contains only the event identity, the event type, and a pointer to the resource through resource.type + resource.id. Your integration then fetches the full resource detail from the Fintoro API version it already uses.
When to use webhooks
- when you need to react to create, update, or delete events without building change detection around frequent polling,
- when you want to keep a local cache or downstream system in sync only after a real change,
- when you want to separate event reception from the later fetch of the resource detail.
webhook-id for deduplication, and only then fetch the resource detail from Fintoro API. Leave polling only as a backfill or reconciliation fallback, not as the primary trigger for change handling.
Subscription management
Manage webhook subscriptions directly through the Fintoro API. The plaintext secret is only returned when the subscription is created or when you rotate it manually. For the exact CRUD contract, request schemas, and response payloads, use the Webhook API reference. In practice:- you must store
plainTextSecretsecurely from the create or rotate response, - changing
urlorsubscribedEventsdoes not rotate the secret automatically, isActive = falsedoes not remove history, it only prevents new deliveries.
Endpoint requirements
When you create or update a subscription, a syntactically valid HTTPS URL is not enough on its own. Fintoro validates the endpoint more strictly:urlmust usehttps://,urlmust not contain a username or password,- the hostname must resolve to a public IP address,
localhost,.local, private ranges, loopback, link-local, and other reserved addresses are rejected by the backend.
Delivery payload
The webhook payload is intentionally thin:Field semantics
The payload does not include:
- an API version,
- an absolute or relative resource URL,
- a full resource snapshot,
- embedded lookups or nested business objects.
Delivery headers
Every webhook request includes these headers:webhook-id and webhook-timestamp are not assembled into a separate canonical string. The signature is calculated from the raw request body exactly as it was delivered.
Signature verification
Signature verification should have four layers:- check that all required webhook headers are present,
- check that
webhook-timestampis not too old or too far in the future, - compute HMAC SHA-256 over the raw request body and compare it in constant time,
- deduplicate by
webhook-idso that retries remain safe to process.
Recommended flow
Pseudocode
JavaScript / Node.js-like example
How to respond to a delivery
- Return
2xxonly after the request has been safely received, verified, and stored for downstream processing. - If the signature or timestamp is invalid, return
401or your receiver-specific auth failure. - If a downstream dependency is temporarily unavailable and you want a retry, return a non-
2xxstatus. - If you accept the request and only enqueue internal work,
204 No Contentis perfectly fine.
- idempotent,
- resilient to duplicates,
- able to return
2xxfor an already processedwebhook-id.
Retry mechanism
Fintoro treats a delivery as failed when:- the receiver returns a non-
2xxHTTP status, - the request times out,
- a network-level send error occurs.
- the endpoint no longer passes the pre-send URL, DNS, and IP safety validation.
In practice, the typical sequence looks like this:
After all attempts are exhausted, the delivery is marked as finally failed. The subscription is not automatically disabled just because one or more deliveries failed.
From the receiver perspective, it is important to:
- never assume exactly-once delivery,
- expect the same
webhook-idto arrive more than once, - respond quickly and move heavier logic to your internal queue,
- return non-
2xxonly when you actually want Fintoro to retry the delivery.
Thin payload and the follow-up detail fetch
Recommended integration flow:- receive the webhook and verify the signature,
- deduplicate by
webhook-id, - determine the correct detail endpoint from
typeandresource, - fetch the resource detail from the Fintoro API version used by your integration,
- run business logic only on the fetched detail.
clients.updated+resource.id = 42→GET /clients/42invoices.created+resource.id = 301→GET /invoices/301warehouse-outbound-receipts.deleted+resource.id = 88→ if the detail is already gone, process the delete locally from the event itself
Available events
Master data
CRM
Warehouses and catalog
Documents
Production recommendations
- do not run heavy business logic directly in the receiver HTTP thread,
- persist the raw payload and
webhook-idbefore downstream processing, - rotate secrets in a controlled way and coordinate rollout with the receiver,
- monitor retry patterns and repeated non-
2xxresponses as an indicator of a receiver-side incident, - log
webhook-id,type,resource.type,resource.id, and theX-Request-Idfrom the later resource fetch, - for delete events, do not assume the detail endpoint can still return the deleted resource.

