Skip to main content
Uses: Python · TypeScript · CLI · REST API
A trigger watches a connected app and POSTs each event it captures to an HTTPS endpoint you own - a destination. This recipe goes from nothing to a receiver that accepts only genuine Engini deliveries. The sequence is destination → trigger → enable → test → receive.
cURL samples assume BASE=https://api.engini.io/v1 and AUTH="x-api-key: $ENGINI_API_KEY" - the setup from the REST walkthrough. The trigger type and connection (monday_item_created, connection 12) are placeholders - list what your connections can fire on with GET /v1/triggers/types.

1. Register a destination

The response carries the signing secret, and this is the only time you will see it. Store it in your secret manager before doing anything else.
Keep the whole esec_… string. The prefix is part of the HMAC key - a receiver that strips it computes a signature that never matches. Lost the secret? Rotate it (rotate-secret); nothing reads it back.
Because this destination is the account default, every trigger that names no destination delivers here. Pass destination_id when you create a trigger to send it somewhere else.

2. Create the trigger and enable it

Read the type first: whether it takes a schedule, listen_columns, or neither depends on the type. Then create it - and enable it, because a trigger is created disabled.
status should now read enabled. If enable fails with 502 TRIGGER_SUBSCRIBE_FAILED, the provider refused the subscription - GET the trigger and it reads errored / subscribe_failed.

3. Write the receiver

Three rules, and each one is a bug if you skip it:
  1. Verify against the raw body bytes. Parsing the JSON and re-serialising it changes the bytes the signature covers.
  2. Deduplicate on X-Engini-Event-Id. Delivery is at-least-once, and every retry is signed afresh, so the signature is different each time while the event id stays the same.
  3. Answer within 10 seconds. A slower attempt counts as failed and is retried. Acknowledge first, then do the work.
verify_webhook / verifyWebhook raises on a missing, malformed or wrong signature, or a timestamp more than 300 seconds from now, and returns the parsed event on success. Writing it by hand in another language? The scheme is in Verifying a delivery.
Pick the status code on purpose. 408, 429 and 5xx are retried (1 min, 5 min, 15 min, 1 h, 6 h). Any other 4xx - and any redirect - dead-letters that event at once, and five dead-letters in a row auto-disable the destination. So a receiver deployed with the wrong secret switches its own deliveries off within five events. Return 503 if your own backend is down and you want Engini to try again later.

4. Prove the wiring with a test event

You don’t need to wait for someone to change a monday item. POST /v1/triggers/{id}/test signs a synthetic event with the destination’s real secret, sends it straight away, and tells you what your receiver answered.
The test endpoint is API-only for now - neither SDK nor the CLI wraps it yet. It is limited to 10 calls a minute per account.
A test event is never stored: it won’t show up in the event log or count against deduplication. Its id starts te_test_ and its body has "test": true, which is why the receivers above can skip it.

Next