Hooks

Automations that watch for something and then act on it. Hooks covers what starts a hook, the ordered actions it runs, the payload those actions share, and where a failure shows up.

What a hook is

A hook is an automation with two halves. One trigger decides when it runs, and one or more actions decide what happens. Nothing else sits between them. When the trigger fires, Countly hands its payload to the first action, that action runs, then the next, in the order you arranged them.

The trigger is the whole of the "when". Four kinds exist and only one can be on a hook at a time. An API endpoint trigger gives the hook a dedicated URL and fires when something calls it. A Tracked data trigger fires the moment matching SDK data arrives from the project, optionally narrowed by conditions on the event's properties. An Internal activity trigger fires on something Countly itself did, like a profile entering a cohort or an alert going off. A Schedule trigger fires on a recurring day and hour rather than in response to data.

The actions are the whole of the "then". An action can send an HTTP request, send an email, or run a piece of JavaScript in a sandbox. A hook needs at least one and can hold as many as you like. They run in the order shown in the editor, one after another, and a failure in one does not stop the ones after it.

Every hook belongs to one project. The project decides whose data drives the trigger and whose permissions govern who can edit the hook. A hook created through the dashboard always names a single project. A hook written directly against the API can list several, and every one of them can fire it; the editor shows them all and saves them back as they are.

A hook is either enabled or disabled. A disabled hook keeps its full definition, its trigger and its actions, and simply never runs. Turning it back on resumes it with nothing to re-enter.

The payload actions share

Every hook run carries one object from stage to stage, and that object is the payload. What starts in it depends on the trigger. An API endpoint trigger contributes whatever query parameters the caller sent, or the JSON body on a POST. A Tracked data trigger contributes the incoming event or session, with its properties. An Internal activity trigger contributes what Countly knows about the thing that happened, such as the profile and the cohort it entered. A Schedule trigger contributes nothing at all, because no data caused it.

Actions read the payload but do not change it. Two actions in a row receive exactly the same object, so ordering an email after an HTTP request does not mean the email sees the request's response. The one exception is a Run custom code action. Its code gets the payload as a variable named params, and whatever params holds when the code finishes becomes the input for every action after it. That makes custom code the only way to reshape, filter, or enrich what later actions receive.

HTTP and email actions insert payload values through template tokens rather than code. Insert data in the editor lists the fields the trigger actually produces and writes the token for you. Two special tokens always work: {{payload_json}} puts the whole payload in as JSON, and {{payload_string}} puts it in as text. A custom code action further up the chain changes what the fields below those two are, which is why the picker suggests running a test to see the real field names.

A custom code action placed last is a common mistake worth naming. It reshapes the payload for the next action, and if there is no next action its result is not used. The editor flags it, but the fix is always the same: add a delivery action after it.

Use Cases

Forward an event to another system

The most common hook forwards something that just happened to a system outside Countly. A signup event reaches a CRM, a purchase reaches a billing tool, a crash reaches a chat channel.

Open New hook. On the Setup step, pick the project whose data you want to watch, then set the trigger type to Tracked data. Pick the event by name rather than leaving it on Any tracked data, or the hook fires on every session and every event the project receives. If only some of those events should count, turn on conditions and add them against the event's own properties.

Move to the Actions step. Set the first action to Make an HTTP request, then fill in the destination URL and choose the method. For a POST, put the payload in the request data field. The fastest way is Insert data, which lists the fields this trigger really produces and writes the token for you. A body of {{payload_json}} sends the whole thing as JSON, which is what most receiving systems want. Add headers if the destination needs an API key or a content type.

Run Test hook before you go further. The test sends a real request to that real URL, so point it at something you are happy to receive traffic on. The result strip on the action card shows the response, and a failure shows the error the request came back with.

Then create it. The name has filled itself in as the action plus the trigger, which is usually good enough to find the hook later; change it on Setup if not. A new hook starts running as soon as it is created. Give the server a few seconds to pick up the new rule before you expect the first run.

Email a team when something happens in Countly

Some of the most useful hooks watch Countly itself rather than incoming data. A profile entering a high-value cohort, an alert firing, a project being created: each of those is an internal action, and each can send an email.

On the Setup step, set the trigger type to Internal activity and pick the activity from the list. Several of them need a second choice before the hook is complete. Cohort entry and Cohort exit need the cohort. Profile group entry and Profile group exit need the profile group. Hook triggered needs the upstream hook whose run should start this one. Alert triggered can name the alert, or stay empty and run for every alert that picks this hook in its own delivery settings. If the project has no alerts at all the form says so, because a hook waiting on an alert that does not exist will never run.

On the Actions step, set the action type to Send an email and add the recipient addresses. Addresses are not checked against your member list, so a hook can email someone who has never signed in to Countly.

Leave the email body empty and the message carries the raw payload, formatted as readable JSON. That is fine for a channel that just needs the facts. Write a body instead and it goes out as your text with the payload values substituted in, again through Insert data. Either way, set a Subject so the team can tell this hook's emails apart; left empty, the subject is the hook's name.

Run Test hook once. A test really sends the email, so send it to yourself first and add the rest of the recipients afterwards.

Reshape a payload before sending it

A receiving system rarely wants Countly's payload exactly as it arrives. It wants three fields out of thirty, or a different shape, or a computed value that is not in the data at all. A Run custom code action in front of the delivery action does that.

Add two actions on the Actions step and keep them in this order: Run custom code first, then the action that delivers. Select the code action in the rail on the left and write against params, which holds the payload the code receives. Reassign or edit params, and whatever it holds when the code finishes is what the next action gets. The Snippets menu drops in working starting points for reshaping a payload, adding computed fields, or building a message body.

The code runs in a sandbox with real limits. It gets three seconds and 128 MB, it cannot reach the network or the filesystem, and it has no access to the rest of Countly. Anything slower or larger than that belongs on the other side of an HTTP action.

Now select the delivery action. Its Insert data list still shows the trigger's original fields, with a note saying a custom code action reshapes the payload before this one. Run Test hook and the note resolves itself: after a test, the picker lists the fields your code actually produced, because the test recorded what each stage passed along.

The one arrangement to avoid is ending on the code action. It shapes the payload for the next action, so as the last action its result is discarded. The editor points this out, and the fix is to add a delivery action after it.

Test a hook before enabling it

Test hook sits on the Actions step and runs the whole pipeline once, on demand. It is the only way to see what a hook does before real data reaches it.

Understand what a test is before you press it. It is not a simulation. The actions really run: emails are really sent, HTTP requests are really made, and custom code is really executed. The button carries that warning as a tooltip. What a test does not do is touch the hook's history. It does not raise the trigger count and it does not write a failure into the detail page's log, so testing repeatedly leaves no trace.

The button is disabled until the draft is complete, because a hook with a missing URL or no recipients has nothing to run. Its tooltip then asks you to fix the outstanding issues instead of showing the warning.

Results land on the pipeline rail as one strip per action, marked OK, Failed, Check logs or Not reached. Clicking a strip opens that action's error and the payload it passed on, under the editor. Read them in order: the run stops at the first action that produces nothing, and every action after it shows as Not reached.

Two results deserve a second look. If a note under the trigger says it did not match the sample payload, no action ran at all and the problem is on the Setup step. Only an API endpoint trigger is really matched in a test; the other three pass the sample payload straight through, so a test does not check Tracked data conditions. If an HTTP action fails immediately with an address complaint, the URL is being refused rather than attempted. Countly checks destination URLs against internal and private addresses both when a hook is saved and when it runs.

FAQs

Why does the list show hooks from projects I am not looking at?

Because a hook belongs to a project of its own and switching the top-bar project does not change what you manage. Scoping the page would hide most of your hooks. Use the Project filter when you want it narrowed.

Does Test hook actually send things?

Yes. Emails are sent, HTTP requests are made, and custom code is executed against whatever it can reach. What a test skips is the bookkeeping: it does not raise the trigger count and it does not write a failure into the log. Point the actions at yourself while you are still drafting.

Why did my new hook not run straight away?

The server picks up rule changes on a short cycle, about three seconds. A hook saved a moment ago is not live until that refresh happens, so data arriving in the same instant can slip past it.

The run count is going up but nothing is arriving. Why?

The count records runs of the trigger, not successful deliveries. Open the hook's detail page and read the Failed runs list at the bottom, which is the only place the reason appears.

Why is my HTTP action refused before it even tries?

The destination is being blocked as an internal or private address. Countly checks the URL both when the hook is saved and each time it runs, so a hook cannot be pointed back inside the network the server lives in.

Why was my HTTP action not sent, with a message that it would trigger the hook again?

The request sends data into a project the hook itself watches, such as a Tracked data hook that starts a session in its own project. Each request would trigger the hook again, without end. Send the data to a different project, or watch a different event.

Why did my hook stop running for a while?

Each hook may run a limited number of times in a time window, 100 times a minute unless your administrator changed it. Runs over the limit skip their actions and appear in Failed runs as "call limit reached", and the hook runs again once the window ends. Administrators set the limit in Server Settings under Hooks.

Can I change the subject line of the email a hook sends?

Yes. Set it in the email action's Subject field, with tokens as in the body. Left empty, the subject is the hook's name.

Why did my actions disappear when I changed the trigger?

Because the tokens and snippets in your actions name fields of the payload the old trigger produced. A different trigger produces a different payload, so those references would point at nothing, and the chain restarts. Choosing a different activity on an Internal activity trigger resets them too. Editing within the same type otherwise, like changing the event or the hour, leaves the actions alone.

My custom code runs but the next action does not see the result.

Check that the code action is not last in the chain. It shapes the payload for whatever follows it, so with nothing following, the result is discarded. Also check that the code assigns back to params, which is the variable the next action reads.

Related Resources

Was this page helpful?
Reach out to us for any other questions.
Helpful?

Looking For More Help?