Search docs.molo17.com
    Configuration guide Control Plane

    Send platform events to webhooks

    Core Hub can call an HTTP endpoint every time something happens on the platform: an entity starts, an entity stops, a pipeline fails. This guide creates a webhook in the Control Plane, explains every field, and then shows real payloads arriving at a test receiver, together with the delivery log and the dead-letter queue that Core Hub keeps for each attempt.

    In this guide

    You will learn how to prepare a receiver, create and test a webhook, choose the events and severities it receives, verify its signature, trigger real events, read the payloads, review the delivery log, and retry a failed delivery.

    Quick information

    Goal

    Deliver Gluesync platform events to an HTTP endpoint and verify them

    Audience

    Gluesync administrators and integration developers

    Level

    Intermediate

    Time required

    About 40 minutes

    Area

    Control Plane → Settings → Notifications → Webhooks

    Applies to

    Gluesync 2.3

    Before you begin

    Make sure that:

    1. You can sign in to the Gluesync Control Plane with a user that can change platform settings;

    2. You have an HTTP endpoint that Core Hub can reach from its own network, and a way to see the requests it receives;

    3. A test pipeline with a running entity is available, and you can change its target in a database tool. The guide makes a target table reject writes on purpose, so do not use a production pipeline.

    This guide was tested with webhook-tester, a receiver that shows every request it gets. You open it in your browser at http://localhost:8091, but Core Hub reaches it at http://webhook-tester:8080/<session-id>; from inside its container network. Always give the webhook the address that Core Hub can use, not the one that your browser uses. The test pipeline is called Alerts demo and replicates a customers entity into the shop_alerts schema of a PostgreSQL target.

    Guide steps

    Create a receiving session

    UI

    1. Open the receiver in your browser (here http://localhost:8091). It creates a session with a unique URL;

    2. Note the session ID, the last part of the URL;

    3. Build the address that Core Hub must call: the host and port that Core Hub uses to reach the receiver, followed by the session ID. For webhook-tester that is http://webhook-tester:8080/<session-id>;.

    The WebHook Tester page with the unique session URL marked by annotation 1 and the New URL button marked by annotation 2
    Figure 1. The unique URL of the session (1). Select New URL (2) for another session.
    Expected result

    You have the endpoint URL for the webhook, and the receiver shows no requests yet.

    Open the webhooks settings

    UI

    1. Select the Settings gear icon in the header;

    2. Select Notifications;

    3. Select the Webhooks tab;

    4. Select Add webhook.

    The Notifications settings with the Webhooks tab marked by annotation 1 and the Add webhook button marked by annotation 2
    Figure 2. Open the Webhooks tab (1) and select Add webhook (2).
    Expected result

    A New webhook form opens below the list of existing webhooks. The list shows one card per webhook with its endpoint and badges for the enabled state, the number of events and severities, Signed, and custom headers.

    Describe the webhook and its endpoint

    UI

    1. Keep Webhook enabled selected;

    2. Select Include exception stack trace in payload (error/critical events) if the receiver should get the stack trace of failures;

    3. In Name, enter a label for the list and for the delivery logs. This guide uses Alerts demo webhook;

    4. In Endpoint URL, enter the address of the receiver;

    5. In Signing secret (optional), enter a secret if the receiver must verify that a request comes from Core Hub. This guide uses a dummy value;

    6. In Description (optional), enter a note for your colleagues.

    The New webhook form with Webhook enabled
    Figure 3. Fill in the identity and delivery fields (1 to 6).
    Field What it does

    Webhook enabled

    When cleared, Core Hub sends nothing to this webhook, but keeps its configuration.

    Include exception stack trace in payload (error/critical events)

    Adds the stackTrace field to error payloads. It is off by default, which keeps payloads small.

    Name

    Friendly identifier shown in the list and in the Webhook column of the delivery logs.

    Endpoint URL

    Address that receives the POST request. Core Hub always sends a JSON body with a POST; there is no method option and no query string. The form hint mentions HTTPS, but a plain http:// address works inside a private network.

    Signing secret (optional)

    When set, Core Hub signs the request body with HMAC-SHA256 and sends the result in the X-Gluesync-Signature header. The field is masked. Leave it empty for unsigned deliveries.

    Description (optional)

    Free text. It is not sent to the endpoint.

    Expected result

    The form shows your values, and the signing secret is masked.

    Choose the scope, the events, and the severities

    UI

    1. In Objects filters, select a Pipeline, Group, or Entity to restrict the webhook to those objects. This guide selects the pipeline Alerts demo. With the three filters empty, events from every object are delivered;

    2. In Enabled events, open the list and tick the event types to deliver. This guide ticks Entity Snapshot Started, Entity Snapshot Completed, Entity CDC Started, Entity CDC Stopped, Pipeline Error, and Pipeline Error Resolved. Select Select all or Clear to change every entry at once;

    3. In Severity filter, tick Critical, Info, and Warning.

    The Objects filters
    Figure 4. Select the pipeline (1), 6 of the 40 event types (2), and all 3 severities (3).

    Select at least one severity. A webhook with no severity selected receives no events at all, not every event. The same applies to Enabled events: select the types you need.

    Expected result

    The Enabled events dropdown reads 6 of 40 selected and the Severity filter dropdown reads 3 of 3 selected.

    Add a header, review the TLS option, and test the webhook

    UI

    1. Select Add header;

    2. In Header name, enter X-Demo-Source, and in Value, enter alerts-demo. Core Hub adds every header you define to each request. It ignores the reserved names X-Gluesync-Event, X-Gluesync-Delivery, X-Gluesync-Signature, Host, Content-Length, and Content-Type;

    3. Leave Skip TLS verification cleared. Select it only for an HTTPS endpoint with a self-signed or internal certificate that the Core Hub trust store does not know;

    4. Select Send test;

    5. Scroll up to the top of the Webhooks tab.

    The custom header row marked by annotation 1
    Figure 5. Add the header (1), review Skip TLS verification (2), then select Send test (3). Create webhook (4) saves the webhook.
    The top of the Webhooks tab with the Success message Test webhook sent to the endpoint URL marked by annotation 1
    Figure 6. A green Success message (1) confirms that the test request was sent.
    Expected result

    The message Success: Test webhook sent to <endpoint URL>. appears above the list, and the receiver shows one request. Send test uses the values currently in the form, so you can test before you save. A test event is not written to the delivery log.

    The Success message does not prove that the endpoint received the event. In this release it also appears when the endpoint refuses the connection (the request is retried for about 7 seconds first). Always confirm the test in the receiver.

    Create the webhook

    UI

    1. Scroll down to the end of the form;

    2. Select Create webhook.

    The list of webhooks with the new Alerts demo webhook card marked by annotation 1
    Figure 7. The new card (1) shows the enabled state, 6 events, 3 severities, Signed, and 1 header.
    Expected result

    The form closes and the Alerts demo webhook card appears in the list. From now on, Core Hub delivers matching events to the endpoint without a restart.

    The Retention section below the list applies to the delivery logs and dead letters of every webhook, not only yours. This guide leaves its values unchanged.

    Inspect the test request

    UI

    1. In the receiver, select the request that arrived;

    2. Review the HTTP headers. Select Show all headers if the list is cut;

    3. Review the request body.

    The receiver showing the HTTP headers marked by annotation 1 and the JSON request body of the test event marked by annotation 2
    Figure 8. The headers (1) identify the event, the delivery, and the signature. The body (2) is the CloudEvents JSON document.

    Every delivery carries these headers:

    Header Value

    X-Gluesync-Event

    The event type, for example gluesync.webhook.test or gluesync.pipeline.error.

    X-Gluesync-Delivery

    A unique identifier of the delivery. It equals the id field of the body.

    X-Gluesync-Signature

    sha256= followed by the HMAC-SHA256 of the raw request body, written in hexadecimal. Present only when a signing secret is set.

    X-Demo-Source

    The custom header that you defined.

    To verify a signature, compute the HMAC-SHA256 of the raw body with the same secret and compare it with the header:

    import hashlib, hmac
    
    def is_valid(body: bytes, secret: str, header: str) -> bool:
        expected = "sha256=" + hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
        return hmac.compare_digest(expected, header)
    Expected result

    The test event has "type": "gluesync.webhook.test" and "severity": "INFO", and is_valid returns True for the body and the secret you entered.

    Trigger real events by starting and pausing an entity

    UI

    Use the pipeline that the webhook is scoped to.

    1. Open the pipeline and select the play icon in the row of a paused entity;

    2. In the start dialog, keep Where it stopped and select Start entity;

    3. Wait a few seconds, then select the pause icon in the same row;

    4. In the Pause customers dialog, select Pause entity.

    The entities table with the play icon of the customers entity marked by annotation 1
    Figure 9. Select the play icon of the entity.
    The Sync changes dialog with Where it stopped marked by annotation 1 and Start entity marked by annotation 2
    Figure 10. Continue from the last checkpoint (1) and select Start entity (2).
    The Pause customers dialog with the Pause entity button marked by annotation 1
    Figure 11. Confirm with Pause entity.
    The receiver showing the request for the entity CDC stopped event with the headers marked by annotation 1 and the body marked by annotation 2
    Figure 12. The request for gluesync.entity.cdc.stopped: headers (1) and body (2).
    Expected result

    The receiver lists a request for gluesync.entity.cdc.started after the start and a request for gluesync.entity.cdc.stopped after the pause. Both have the severity INFO and name the pipeline Alerts demo and the entity customers.

    Trigger a failure

    UI SQL

    Make the target table reject writes, then start the entity so that it must write.

    1. In your database tool, connect to the target database of the test pipeline and run:

      ALTER TABLE shop_alerts.customers
        ADD CONSTRAINT alerts_demo_block CHECK (false) NOT VALID;

      NOT VALID leaves existing rows alone and rejects every new or updated row;

    2. In the Control Plane, select the play icon of the paused entity;

    3. In the start dialog, select Full copy, keep Keep and merge, and select Start entity;

    4. Wait about 20 seconds and review the receiver.

    The start dialog with Full copy marked by annotation 1
    Figure 13. Start with Full copy (1) and Keep and merge (2) so that the entity writes every row again.
    The receiver showing the pipeline error request with the headers marked by annotation 1 and the body marked by annotation 2
    Figure 14. The request for gluesync.pipeline.error has the severity CRITICAL.
    Expected result

    The entity shows the error status and the receiver gets several gluesync.pipeline.error requests with the severity CRITICAL, one for each failed write attempt. The message field carries the database error, and the stackTrace field is present because you selected Include exception stack trace in payload (error/critical events).

    The database message can include the values of the row that failed. The payload leaves Core Hub and reaches every system you configure, so use the stack trace option and the receiver with the same care as the data itself.

    Undo the failure

    SQL

    1. In your database tool, run:

      ALTER TABLE shop_alerts.customers
        DROP CONSTRAINT alerts_demo_block;
    2. Watch the receiver and the entity row.

    Expected result

    Core Hub retries the write. The receiver gets gluesync.entity.snapshot.completed followed by gluesync.entity.cdc.started, and the entity runs again.

    Review the delivery log

    UI

    1. In Settings, open Notifications and the Webhooks tab;

    2. Scroll to Delivery logs;

    3. Compare the rows with the requests that the receiver got. Select Refresh to load the latest attempts.

    The Delivery logs table with failed rows marked by annotation 1
    Figure 15. Failed attempts (1) show Fail, a dash in HTTP, and the total duration. Successful ones (2) show OK and the status 200. Select Refresh (3) to reload.
    Column What it shows

    Status

    OK when the endpoint answered with a 2xx code, Fail when every attempt failed.

    Event

    The event type of the delivery, for example Gluesync.entity.cdc.started.

    Webhook

    The Name of the webhook that received the delivery.

    HTTP

    The status code of the last answer, or a dash when the endpoint never answered.

    Duration

    The time of the whole delivery, retries included.

    Time

    The moment of the delivery.

    Expected result

    Your pipeline events appear with the webhook name Alerts demo webhook, the status OK, and the HTTP code 200.

    The delivery log is shared: it lists the deliveries of every webhook and every pipeline on the platform, 20 rows per page. Use the Webhook column to find your rows. Purge logs deletes the log of everyone, so do not use it on a shared system.

    See a failed delivery and retry it

    UI

    When an endpoint does not answer, Core Hub retries the delivery and, if every attempt fails, moves it to the dead letters. To see one, create a temporary second webhook.

    1. Select Add webhook and enter Alerts demo unreachable as the Name and http://webhook-tester:9/unreachable as the Endpoint URL, an address where nothing listens;

    2. Scope it to the pipeline Alerts demo, tick Entity CDC Started and Entity CDC Stopped, tick all three severities, and select Create webhook;

    3. Pause and start the entity again, as before;

    4. Wait about 10 seconds and select Refresh under Dead letters;

    5. Open the temporary webhook with its pencil icon, replace the Endpoint URL with the working address of your receiver, and select Save changes;

    6. In Dead letters, select Retry in each row.

    The Dead letters table with two failed deliveries marked by annotation 1 and the Retry link marked by annotation 2
    Figure 16. Each failed delivery (1) is a dead letter. Select Retry (2) to send it again.
    The Dead letters section showing No dead letters yet
    Figure 17. After the retries, the queue is empty (1).
    Expected result

    The two failed deliveries are listed in Dead letters with HTTP — and a duration of about 7 seconds, which is the time of the original attempt plus its retries. After you correct the endpoint and select Retry, the rows disappear and the receiver gets the two events. Retry uses the current configuration of the webhook, so it reaches the corrected address.

    When you are done, select the bin icon of the temporary webhook and select Confirm to delete it. Dead letters are shared like the delivery log, and Purge dead letters removes the entries of every webhook.

    Read the payload

    Every delivery is a JSON document that follows the CloudEvents structure. This is the request that Core Hub sent when the entity was paused, as the receiver showed it:

    {
      "specversion": "1.0",
      "id": "a215e9d7-7ff2-4050-a59e-6e2f7835d185",
      "source": "gluesync",
      "type": "gluesync.entity.cdc.stopped",
      "time": "2026-10-28T11:41:50.600327382Z",
      "datacontenttype": "application/json",
      "severity": "INFO",
      "pipelineId": "07a09a3f",
      "pipelineName": "Alerts demo",
      "entityId": "612148ff",
      "entityName": "customers",
      "groupId": "_default",
      "groupName": "default",
      "message": "CDC task for customers has been stopped in pipeline Alerts demo at 11:41 10-28-2026",
      "eventSource": { "kind": "entity", "id": "612148ff" },
      "data": { "source": { "kind": "entity", "id": "612148ff" } }
    }

    And this is the failure, trimmed (message and stackTrace shortened):

    {
      "specversion": "1.0",
      "id": "ad8f5785-c903-4dc0-b874-c58cc32aef07",
      "source": "gluesync",
      "type": "gluesync.pipeline.error",
      "time": "2026-10-28T11:42:07.886153126Z",
      "datacontenttype": "application/json",
      "severity": "CRITICAL",
      "pipelineId": "07a09a3f",
      "pipelineName": "Alerts demo",
      "entityId": "612148ff",
      "entityName": "customers",
      "agentId": "e5fbb265",
      "message": "ERROR: new row for relation \"customers\" violates check constraint \"alerts_demo_block\" ...",
      "stackTrace": "com.molo17.gluesync.commons.model.exception.TargetWritingException: ERROR: new row ...",
      "eventSource": { "kind": "entity", "id": "612148ff" },
      "data": { "source": { "kind": "entity", "id": "612148ff" } }
    }
    Field Meaning

    id

    Unique identifier of the delivery, the same as X-Gluesync-Delivery.

    type

    Event type, the same as X-Gluesync-Event. The events of this guide are gluesync.entity.cdc.started, gluesync.entity.cdc.stopped, gluesync.entity.snapshot.completed, gluesync.pipeline.error, and gluesync.webhook.test.

    time

    When Core Hub created the event, in UTC.

    severity

    INFO, WARNING, or CRITICAL. This is the value that the Severity filter compares.

    pipelineId, pipelineName, entityId, entityName, groupId, groupName, agentId

    The objects the event belongs to. A field is missing when the event has no such object.

    message

    Human-readable text of the event.

    stackTrace

    The exception stack trace. Present only on error events of webhooks that have Include exception stack trace in payload (error/critical events) selected.

    eventSource, data.source

    The kind and the identifier of the object that raised the event.

    Pausing an entity raises gluesync.entity.cdc.stopped with the severity INFO, not WARNING. Select Info in the Severity filter if you want to react to it.

    Verify the result

    You have successfully set up platform webhooks if:

    • The webhook card shows Enabled, Signed, and the numbers of events and severities you chose;

    • Send test showed Success and the receiver got a gluesync.webhook.test request;

    • The signature of a request verifies with your secret;

    • Starting and pausing the entity produced gluesync.entity.cdc.started and gluesync.entity.cdc.stopped requests;

    • The failing write produced gluesync.pipeline.error requests with the severity CRITICAL;

    • Delivery logs lists the deliveries, and Dead letters is empty after you retried the failed ones.

    Troubleshooting

    Problem Possible cause What to do

    Send test shows Success but the receiver shows no request

    The endpoint is unreachable from Core Hub. The message appears even when the delivery failed

    Use the address that Core Hub can reach, not the one your browser uses (for a container, the container network name), then send the test again

    The test arrives but real events do not

    The event type or the severity is not selected, or the Objects filters exclude the pipeline

    Open the webhook, check Enabled events, Severity filter, and Objects filters, and select Save changes

    The webhook receives no event and shows 0 severities

    No severity is selected, which delivers nothing

    Select Critical, Info, and Warning, or the severities you need, and save

    Pausing an entity does not reach a webhook that accepts only Warning and Critical

    Entity CDC Stopped has the severity INFO

    Add Info to the Severity filter

    The receiver cannot verify the signature

    The secret differs, or the body was parsed and serialized again before hashing

    Hash the raw request body, byte for byte, with the same Signing secret (optional)

    A delivery shows Fail in the delivery log

    The endpoint did not answer or returned a status outside 2xx after all attempts

    Fix the endpoint, then select Retry on the row in Dead letters

    Contact MOLO17 Support if you need assistance with webhooks.