# Custom hook

At the end of each sync run, the Sync Engine lists all stored procedures named `SYNC_RUN_POST_HOOK`, with a single `object` parameter. All that exist are executed with the following parameter value:

```
{
  "branch_id": <the id of the branch, or null>,
  "new_health_state": <the new health state of the run, e.g. "HEALTHY">,
  "sync_id": <the id of the sync>,
  "sync_run_id": <the id of the sync run>
}
```

Note: Health states are listed [here](https://docs.omnata.com/omnata-product-documentation/omnata-sync-for-snowflake/how-it-works/terminology#sync-health-states).

Below is an example of a hook which simply writes the run information to a table:

```
create table TEST_HOOK_LOG(payload OBJECT);

CREATE OR REPLACE PROCEDURE SYNC_RUN_POST_HOOK(result OBJECT)
RETURNS VARCHAR NOT NULL
LANGUAGE SQL
EXECUTE AS OWNER
AS
BEGIN
  INSERT INTO TEST_HOOK_LOG select :result;
  RETURN 'Rows inserted: ' || SQLROWCOUNT;
END;

grant usage on procedure SYNC_RUN_POST_HOOK(OBJECT) to application OMNATA_SYNC_ENGINE;

-- you also need to grant usage on SYNC_RUN_POST_HOOK's database and schema
grant usage on database <DB> to application OMNATA_SYNC_ENGINE;
grant usage on schema <DB>.<Schema> to application OMNATA_SYNC_ENGINE;

```

{% hint style="warning" %}
The procedure must be created with Owners rights, or an error will be raised.

The Sync Engine will wait for the procedure to complete before the run finishes, so it may be better to start a task for log running processes.
{% endhint %}
