Skip to main content
Webhooks let Melio notify your system when something changes, so you don’t have to poll. When a subscribed event occurs, Melio sends an HTTP POST to the endpoint you registered. Each partner has a single webhook endpoint. You manage it through the /webhook resource and choose which event types it receives.

Managing your endpoint

Creating or updating

PATCH /webhook is a partial update: only the fields you send are changed.
  • url and events are required the first time (when no endpoint exists yet).
  • Sending events replaces the entire subscription list, so always include the full set you want (at least one).
  • Set isActive: false to pause deliveries without deleting the endpoint, and true to resume.
The endpoint url must be an https URL.

Event types

Delivery payload

Each delivery is a lightweight notification. It identifies the affected resource, not its full state. Treat the payload as a signal to fetch the current resource (for example GET /payments/{id}) rather than as the source of truth, so you never act on a stale snapshot. Every delivery includes these fields: Some events carry a small data object; most do not, and you should fetch the resource for its current state. Account created/deleted events include:

Verifying deliveries

Every delivery is signed so you can confirm it genuinely came from Melio and was not tampered with. The raw request body is signed with HMAC-SHA256 (hex encoded) using your API key secret, and the signature is sent in the X-Melio-Signature header. To verify, compute the HMAC over the raw request body (before any JSON parsing) and compare it to the header using a constant-time comparison:
Verify the signature against the raw request body exactly as received. Re-serializing the parsed JSON can change byte-for-byte formatting and produce a different HMAC, causing valid deliveries to fail verification. Reject any delivery whose signature does not match.

Handling deliveries reliably

  • Be idempotent. The same event may be delivered more than once. Deduplicate on messageId (also available as the X-Melio-Delivery-Id header) so you process each event only once.
  • Respond quickly with a 2xx. Acknowledge receipt fast and do heavy work asynchronously. Failed deliveries are retried.
  • Fetch current state. Because deliveries are notifications, always read the resource (GET) to get its latest state before acting, rather than trusting a possibly out-of-order payload.
  • Pause safely. Set isActive: false to stop deliveries during maintenance instead of tearing down and rebuilding your subscription.

Retries and failure handling

Retries and failure handling A delivery succeeds when your endpoint returns a 2xx status. Any other outcome is a failure and Melio retries the delivery: a 4xx, a 5xx, a connection error, or no response at all. Redirects are followed automatically, so the status of the final response is what counts. Point url directly at your handler to avoid spending the attempt on a redirect chain. Retry schedule Melio makes up to 3 attempts per event, spaced roughly 45 minutes apart:
  • Within seconds of the event occurring
  • ~45 minutes after attempt 1 T
  • ~45 minutes after attempt 2 T
he interval is fixed and there is no exponential backoff, so a failing endpoint has about 90 minutes to recover before Melio gives up on an event. After the third failed attempt, the delivery is parked in an internal dead letter queue and is not retried again. Replay events: currently in development and will be part of future planned releases
Retries are per event, not per batch. One failing delivery does not delay or duplicate the deliveries for other events.
Retried failures Condition Retried 4xx response (including 401, 404, 422) Yes 5xx response Yes Connection refused, DNS failure, TLS handshake failure Yes Response not returned in time Yes 2xx response No, treated as delivered Because every failing status is retried, returning a 5xx is a legitimate way to ask for a retry, for example when your own datastore is briefly unavailable. Return a 2xx only once you have durably stored or queued the delivery. Retries do not apply to paused endpoints
While your endpoint is paused (isActive: false) or has no subscription for an event type, Melio does not attempt a delivery at all. Those events are dropped, not buffered. They will not arrive when you set isActive: true again, and they are never retried. Pausing is safe for suppressing traffic during maintenance, but it is not a queue. If you cannot afford to miss events, keep the endpoint active and return a failing status so the delivery is retried instead.
Staying correct across retries Deduplicate on messageId. The same messageId is used for all attempts of the same event, so it is a stable idempotency key. It is also sent as the X-Melio-Delivery-Id header. Treat a delivery whose messageId you have already processed as a no operation and return 2xx. Do not assume ordering. A retried delivery can arrive after newer events for the same resource. A retried api.payment.updated may land after the payment has moved on again. Always GET the resource and act on its current state rather than on the payload, and never rely on occurredAt ordering to drive a state machine. Respond quickly. Acknowledge with a 2xx as soon as the delivery is persisted, and do heavy work asynchronously. A slow handler burns the attempt and forces an unnecessary retry.