> ## Documentation Index
> Fetch the complete documentation index at: https://tyk.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Gateway Events

> Introduction to Gateway Events

Tyk Gateway will generate asynchronous events when certain conditions are met, for example a rate limit being exceeded, an expired key attempting to access an API, or a circuit breaker triggering due to a slow or unresponsive upstream.

Tyk has a flexible model for handling these API events.

## Event categories

There are four different categories of events that can be fired by Tyk:

* [API events](#api-events)
* [Token lifecycle events](#token-lifecycle-events)
* [Advanced quota usage events](#advanced-quota-usage-events)
* [Custom events](#custom-events)

### API events

Tyk can generate (or *fire*) a variety of built-in API events due to activity triggered by an API request, such as exceeded rate limits, depleted quotas or attempts to access using expired keys. The full list of standard API events is available [here](https://tyk.io/docs/api-management/gateway-events.md#api-events).

### Token lifecycle events

Alongside the events that are fired in response to API requests, Tyk will also mark the creation, update or deletion of access tokens (keys) with dedicated events as indicated [here](https://tyk.io/docs/api-management/gateway-events.md#token-lifecycle-events).

### Advanced quota usage events

Tyk will generate [standard quota events](https://tyk.io/docs/api-management/gateway-events.md#standard-quota-events) when a client quota has been consumed, but what if you want to have more granular notification of quota usage as your clients are approaching their quota limit?

For this, Tyk provides [advanced quota monitoring](https://tyk.io/docs/api-management/gateway-events.md#monitoring-quota-consumption) that can be configured to trigger a dedicated event handler when the API usage exceeds different thresholds approaching the quota limit.

### Custom events

The event subsystem has been designed to be easily extensible, so the community can define additional events within the Tyk codebase which can then be handled using the exsiting event handling system.

## Handling events with Tyk

Tyk has a simple event handling system where *event handlers* are assigned (or registered) to the different [events](https://tyk.io/docs/api-management/gateway-events.md#event-types) that Tyk can generate. These handlers are assigned per-API so when an event is generated for an API and there is an *event handler* registered for that *event*, the handler will be triggered.

Three different categories of *event handler* can be registered for each event:

* a [webhook](https://tyk.io/docs/api-management/gateway-events.md#event-handling-with-webhooks) that will call out to an external endpoint
* an [event log](https://tyk.io/docs/api-management/gateway-events.md#logging-api-events-1) that will write to the configured [log output](https://tyk.io/docs/api-management/logs/application-logs.md)
* your own [custom event handler](https://tyk.io/docs/api-management/gateway-events.md#custom-api-event-handlers) that will run in a JavaScript virtual machine on the Tyk server

  > [!NOTE]
  >
  > Remember that **quota usage monitoring** has a [dedicated mechanism](https://tyk.io/docs/api-management/gateway-events.md#monitoring-quota-consumption) for handling these special events.

## Event Types

The built-in events that Tyk Gateway will generate are:

### Rate limit events

* `RatelimitExceeded`: the rate limit has been exceeded for a specific key
* `OrgRateLimitExceeded`: the rate limit has been exceeded for a specific organization
* `RateLimitSmoothingUp`: the [intermediate rate limit allowance](https://tyk.io/docs/api-management/rate-limit.md#rate-limit-smoothing) has been increased for a specific key
* `RateLimitSmoothingDown`: the [intermediate rate limit allowance](https://tyk.io/docs/api-management/rate-limit.md#rate-limit-smoothing) has been decreased for a specific key

### Standard quota events

* `QuotaExceeded`: the quota for a specific key has been exceeded
* `OrgQuotaExceeded`: the quota for a specific organization has been exceeded

### Authentication failure events

* `AuthFailure`: a key has failed authentication (e.g. 401 Unauthorized) or has attempted access and was denied (e.g. 403 Forbidden)
* `KeyExpired`: an attempt has been made to access an API using an expired key
* `UpstreamOAuthError`: an error occurred when trying to authenticate with an upstream using an OAuth provider

### API version events

* `VersionFailure`: a key has attempted access to a version of an API that it does not have permission to access

### Circuit breaker events

* `BreakerTripped`: a circuit breaker on a path has tripped and been taken offline
* `BreakerReset`: a circuit breaker has reset and the path is available again
* `BreakerTriggered`: a circuit breaker has changed state, this is generated when either a `BreakerTripped`, or a `BreakerReset` event occurs; a status code in the metadata passed to the webhook will indicate which of these events was triggered

### Uptime events

* `HostDown`: the uptime checker has found that a host is down/not available
* `HostUp`: the uptime checker has found that a host is available again after being offline

### Token lifecycle events

* `TokenCreated`: a token has been created
* `TokenUpdated`: a token has been changed/updated
* `TokenDeleted`: a token has been deleted

### Certificate expiry events

* `CertificateExpiringSoon`: a certificate has been used within the expiry threshold and should be updated
* `CertificateExpired`: an expired certificate has been used in a request

### OAuth 2.0 events

* `OAuth2ScopeCheckFailed`: a request has a valid OAuth 2.0 access token, but the token does not have the [scopes](https://tyk.io/docs/api-management/authentication/oauth2-authentication.md#scope-enforcement) that the endpoint requires
* `OAuth2ExchangeSucceeded`: Tyk Gateway has [exchanged](https://tyk.io/docs/api-management/authentication/token-exchange.md) an inbound token for an upstream token. This event also fires when the upstream token comes from the cache.
* `OAuth2ExchangeFailed`: a token exchange has failed. The identity provider rejected the exchange or did not respond, or no provider matched the inbound token.

## Event Metadata

Tyk Gateway sends metadata about an event to each *event handler* that you register for that API and event. The external system (webhook) or custom (JavaScript) code can then use this metadata to decide what action to take.

The field names on this page are the names that a webhook template uses. For example, a template reads the request path as `{{.Meta.Path}}`. Custom event handlers receive the same metadata as a JSON object. If the JSON key is different from the field name, the field description shows the JSON key.

### Common Metadata

Most events provide these fields:

**Message** `string`

A human-readable message from Tyk Gateway that provides details about the event.

**OriginatingRequest** `string`

A Base64-encoded [raw inbound request](#raw-request-data).

`OriginatingRequest` is empty for circuit breaker, uptime, token lifecycle, quota monitor and certificate expiry events. It can also be empty for organization quota and rate limit events.

### Specific Event Metadata

Most events also provide fields that are specific to the event. Expand the metadata of an event to see these fields. The list shows `Message` only when the message has a fixed value or a special meaning for that event.

**RatelimitExceeded, RateLimitSmoothingUp, RateLimitSmoothingDown, QuotaExceeded, AuthFailure, KeyExpired** `event`

**metadata**

**Path** `string`

The path of the API endpoint request that led to the event being fired.

**Origin** `string`

The IP address of the client that sent the request.

**Key** `string`

The key that was used in the request.

`Key` has a different value in these cases:

* For an API-level rate limit, `Key` is the internal rate limit key of the API.
* If the key metadata sets `rate_limit_pattern`, rate limit and quota events use the custom key that this pattern creates.
* If a Go plugin fires `AuthFailure`, `Key` is `n/a`.

**OrgQuotaExceeded, OrgRateLimitExceeded** `event`

**metadata**

**Path** `string`

The path of the API endpoint request that led to the event being fired.

**Origin** `string`

The IP address of the client that sent the request.

**Key** `string`

The ID of the organization that exceeded its limit.

**VersionFailure** `event`

**metadata**

**Path** `string`

The path of the API endpoint request that led to the event being fired.

**Origin** `string`

The IP address of the client that sent the request.

**Reason** `string`

The reason why Tyk Gateway rejected the request, for example `This API version does not seem to exist`.

**UpstreamOAuthError** `event`

**metadata**

**Message** `string`

The error that occurred when Tyk Gateway tried to get a token from the upstream OAuth provider.

**APIID** `string`

The ID of the API that triggered the event.

**BreakerTriggered, BreakerTripped, BreakerReset** `event`

**metadata**

**Message** `string`

`Breaker Tripped` or `Breaker Reset`.

**Path** `string`

The path of the endpoint that has the circuit breaker.

**APIID** `string`

The ID of the API that triggered the event.

**CircuitEvent** `integer`

The new state of the circuit breaker, where `0` means tripped and `1` means reset.

**HostDown, HostUp** `event`

**metadata**

**Message** `string`

`Uptime test failed` or `Uptime test succeeded`.

**HostInfo** `object`

The result of the uptime test.

**properties**

**CheckURL** `string`

The URL that the uptime test checked.

**Method** `string`

The HTTP method of the uptime test.

**Protocol** `string`

The protocol of the uptime test.

**Timeout** `duration`

The timeout of the uptime test, for example `10s` in a webhook template or `10000000000` (nanoseconds) in the JSON object.

**Headers** `object`

The headers that the uptime test sent.

**Body** `string`

The body that the uptime test sent.

**Commands** `array`

The commands of a TCP uptime test.

**EnableProxyProtocol** `boolean`

`true` if the uptime test uses the PROXY protocol.

**ResponseCode** `integer`

The HTTP status code that the host returned.

**Latency** `number`

The response time of the host, in milliseconds.

**IsTCPError** `boolean`

`true` if the uptime test failed with a TCP error.

**MetaData** `object`

Extra details about the host, with the keys `api_id`, `host_name` and `target_url`.

**TokenCreated, TokenUpdated, TokenDeleted** `event`

**metadata**

**Org** `string`

The ID of the organization that owns the key.

**Key** `string`

The key that the operation created, updated or deleted.

**TriggerExceeded** `event`

The [quota consumption monitor](#monitoring-quota-consumption) fires this event. Only the monitor webhook receives it.

**metadata**

**Message** `string`

`Quota trigger reached`.

**OrgID** `string`

The ID of the organization.

**Key** `string`

The key that reached the threshold, or empty if an organization threshold fired the event.

**TriggerLimit** `integer`

The threshold that the key or organization reached.

**UsagePercentage** `integer`

The percentage of the quota that the key or organization has used.

**CertificateExpiringSoon** `event`

**metadata**

**CertID** `string`

The certificate ID. The JSON key is `cert_id`.

**CertName** `string`

The name of the certificate. The JSON key is `cert_name`.

**ExpiresAt** `time`

The certificate expiry date. The JSON key is `expires_at`.

**DaysRemaining** `integer`

The remaining days until the certificate expires. The JSON key is `days_remaining`.

**APIID** `string`

The ID of the API that triggered the event. The JSON key is `api_id`.

**CertRole** `string`

`client` for a client certificate or `upstream` for an upstream certificate. The JSON key is `cert_role`.

**CertificateExpired** `event`

**metadata**

**CertID** `string`

The certificate ID. The JSON key is `cert_id`.

**CertName** `string`

The name of the certificate. The JSON key is `cert_name`.

**ExpiredAt** `time`

The date when the certificate expired. The JSON key is `expired_at`.

**DaysSinceExpiry** `integer`

The number of days since the certificate expired. The JSON key is `days_since_expiry`.

**APIID** `string`

The ID of the API that triggered the event. The JSON key is `api_id`.

**CertRole** `string`

`client` for a client certificate or `upstream` for an upstream certificate. The JSON key is `cert_role`.

**OAuth2ScopeCheckFailed** `event`

This event does not provide the common metadata. It provides only these fields.

**metadata**

**oauth2\_api\_id** `string`

The ID of the API that triggered the event.

**path** `string`

The path of the API endpoint request that led to the event being fired.

**method** `string`

The HTTP method of the request.

**required\_scopes** `string[]`

The scopes that Tyk Gateway returned in the `WWW-Authenticate` challenge.

**required\_alternatives** `string[][]`

All the scope combinations that the endpoint accepts.

**granted\_scopes** `string[]`

The scopes in the access token.

**oauth2\_subject\_jti** `string`

The `jti` claim of the access token.

**oauth2\_subject\_azp** `string`

The `azp` claim of the access token.

**OAuth2ExchangeSucceeded, OAuth2ExchangeFailed** `event`

These events do not provide the common metadata. They provide only these fields. For more details, see [token exchange audit events](https://tyk.io/docs/api-management/authentication/token-exchange.md#audit-events).

**metadata**

**oauth2\_api\_id** `string`

The ID of the API that triggered the event.

**oauth2\_provider** `string`

The token exchange provider that Tyk Gateway used, or empty for the `no_matching_provider` outcome.

**oauth2\_exchange\_outcome** `string`

`ok`, `idp_error` or `no_matching_provider`.

**oauth2\_exchange\_cache\_hit** `boolean`

`true` if the exchanged token came from the cache.

**trace\_id** `string`

The trace ID of the request, if present.

**oauth2\_subject\_azp** `string`

The `azp` claim of the inbound token, if present.

**oauth2\_exchanged\_azp** `string`

The `azp` claim of the exchanged token, if present.

**oauth2\_audience** `string`

The audience of the token exchange, if set.

**oauth2\_scopes\_requested** `string[]`

The scopes that Tyk Gateway requested, if set.

**oauth2\_idp\_error** `string`

The error code from the identity provider, for the `idp_error` outcome only.

**oauth2\_idp\_error\_description** `string`

The error description from the identity provider, for the `idp_error` outcome only.

The `ExpiresAt` and `ExpiredAt` fields are Go time values. The JSON object shows them in RFC3339 format. The default webhook template uses the `as_rfc3339` function to get this format. A custom webhook template cannot use this function. Use the Go `Format` method instead, for example `{{.Meta.ExpiresAt.Format "2006-01-02T15:04:05Z07:00"}}`.

### Using the metadata

The metadata are exposed so that they can be used by the event handler (webhook or custom) using Go templating. For details of how each type of event handler can access these data, please see the appropriate section for [webhook](https://tyk.io/docs/api-management/gateway-events.md#webhook-payload) or [custom](https://tyk.io/docs/api-management/gateway-events.md#the-event-object) event handlers.

### Raw Request Data

The `OriginatingRequest` metadata is a Base64-encoded wire-protocol representation of the original request to the event handler. If you are running a service bus or queue that stores failed, throttled or other types of requests, you can decode this object and parse it in order to re-create the original intent of the request (e.g. for post-processing).

### Logging API Events

Tyk’s built-in logging event handler is designed primarily for debugging purposes and will store details of an API event to the configured logger output.

The Tyk platform can be configured to log at various verbosity levels (info, debug, warn, error) and can be integrated with third-party log aggregation tools like Sentry, Logstash, Graylog, and Syslog. For full details on configuring the Tyk logger, see [this section](https://tyk.io/docs/api-management/logs/application-logs.md).

> [!NOTE]
>
> Logging event handlers are currently only supported by Tyk Classic APIs.

### Configuring the event handler

Registering a logging event handler to your Tyk Classic API is the same as adding any other event handler, within the `event_handlers` section of the API definition.

The `handler_name` for the logging event handler should be set to: `eh_log_handler`.

The `handler_meta` for the logging event handler contains a single field:

* `prefix` is a label that will be prepended to each log entry

For example, to register event handlers to log the `AuthFailure` and `KeyExpired` events you might add the following to your API definition:

```json theme={null}
{
  "event_handlers": {
    "events": {
      "AuthFailure": [
        {
          "handler_name": "eh_log_handler",
          "handler_meta": {
            "prefix": "AuthFailureEvent"
          }
        }
      ],
      "KeyExpired": [
        {
          "handler_name": "eh_log_handler",
          "handler_meta": {
            "prefix": "KeyExpiredEvent"
          }
        }
      ]
    }
  }
}
```

In this example

* the `AuthFailure` event will trigger the event handler to generate a log with the prefix `AuthFailureEvent`
* the `KeyExpired` event will trigger the event handler to generate a log with the prefix `KeyExpiredEvent`

When the event handler is triggered an entry will be made in the log containing the corresponding prefix, which can be useful for monitoring and debugging purposes.

## Event handling with webhooks

### Overview

A webhook is a mechanism for real-time, event-driven communication between different systems or applications over the internet. It is an HTTP callback, typically an HTTP POST request that occurs when something happens. Webhooks are real-time, automated and lightweight. Notifications are sent immediately when events occur without the need for the receiving service to poll.

In the context of Tyk Gateway, webhooks are event handlers that can be registered against API Events. The webhook will be triggered when the corresponding event is fired and will send a customizable fixed payload to any open endpoint.

#### When to use webhook event handlers

There are many occasions when you might use webhooks for event handling, here are just a few examples.

##### Rate limit violations

When an API consumer exceeds their allocated rate limit, the `RatelimitExceeded` event will be fired. A webhook event handler can be employed to notify an upstream system to take actions such as updating a dashboard, notifying the account manager, or adjusting the client's service tier.

##### API key lifecycle events

When an expired API key is used to access an API, the client will receive an error and the `KeyExpired` event will be fired. A webhook event handler can be employed to notify an upstream system to take actions such as renewing the key, logging the failure in a CRM or notifying the account manager to initiate customer communication.

##### Upstream service problems

When an API circuit breaker triggers due to an unresponsive upstream service, the `BreakerTripped` event will be fired. A webhook event handler can be employed to update monitoring dashboards or to trigger automated recovery scripts or processes.

#### How webhook event handlers work

With Tyk Gateway, the webhook event handler is a process that runs asynchronously in response to an API event being fired. It will issue an HTTP request to any open endpoint and is fully configurable within the API definition.

The HTTP method, body, header values, and target URL can all be configured in the API definition. The [request body](#webhook-payload) is generated using a Tyk template file that has access to the [event metadata](https://tyk.io/docs/api-management/gateway-events.md#event-metadata).

The webhook event handler runs in its own process and so does not block the operation of the Gateway.

##### Webhook cooldown

It is very likely that an `AuthFailure` event will fire on the same endpoint more than once if the requesting client is automated. If this event triggered a webhook that caused an email to be sent, then if this event occurred 10 times a second, the email recipient would be flooded with emails. In an attempt to mitigate against events such as this, you can set a cooldown timer, in the webhook handler. This prevents the webhook from being triggered again if the event is fired again within the time period specified.

##### Webhook payload

When your webhook event handler is triggered, it will send an HTTP request to the configured target. For HTTP methods that support a request body, for example `POST`, the event handler will process a [Go template](https://tyk.io/docs/api-management/traffic-transformation/go-templates.md) to produce the payload.

If no template is provided in the webhook event handler configuration in the API definition, Tyk Gateway will look for the default file `templates/default_webhook.json`. Any text file accessible to the Gateway can be used to store the Go template to be used by the event handler when constructing the payload.

The event handler has access to the [event metadata](https://tyk.io/docs/api-management/gateway-events.md#event-metadata) and this can be accessed by the template using the `{{.Meta.XXX}}` namespace.

The [event type](https://tyk.io/docs/api-management/gateway-events.md#event-types) that triggered the event handler can be accessed as `{{.Type}}`.

For most event types, the default webhook template has this form:

```json theme={null}
{
  "event": "{{.Type}}",
  "message": "{{.Meta.Message}}",
  "path": "{{.Meta.Path}}",
  "origin": "{{.Meta.Origin}}",
  "key": "{{.Meta.Key}}"
}
```

This would generate a request body (payload) such as:

```json theme={null}
{
  "event": "RatelimitExceeded",
  "message": "API Rate Limit Exceeded",
  "path": "/example-global-webhook/",
  "origin": "99.242.139.220",
  "key": "apilimiter-66336c67cb7191f791f167134b20d1f4c14b4bb5672b57f4b2813c86"
}
```

#### Using webhooks with Tyk Dashboard

Webhook event handlers are configured within the API definition, which is used by Tyk Gateway to determine the appropriate action to be performed in response to a Gateway event.

When using Tyk Dashboard, you are able to create *global webhooks* that can be re-used across multiple events and APIs, allowing you to modify the webhook configuration for a batch of APIs and/or events from one location.

##### Local and global webhooks

Tyk Dashboard supports the declaration of webhooks *globally* and *locally*:

* **Global webhooks** are declared outside the API definition and linked via a *webhook id*; changes to the global webhook definition will be reflected in all APIs that reference that *webhook id*
* **Local webhooks** are fully defined within the API definition; changes to the local webhook configuration will affect only the API within which it is defined

*Global webhook definitions* are registered with the Dashboard using the [UI](#creating-a-global-webhook-definition-using-tyk-dashboard) or [Dashboard API](https://tyk.io/docs/api-reference/webhooks/list-webhooks.md) and assigned a unique *webhook id* that can be obtained via the [Dashboard API](https://tyk.io/docs/api-reference/webhooks/list-webhooks.md) or via drop-down selection within the UI.

If you assign a global webhook definition to an API to handle an event, then Tyk Dashboard will retrieve the definition and update it in the API definition when the API is loaded (or re-loaded) to the Gateway.

##### Creating a global webhook definition using Tyk Dashboard

To create a global webhook definition from the Dashboard UI you should follow these steps:

**Steps for Configuration**

1. **Create the webhook definition**

   Select **Webhooks** from the **API Management** Menu:

   ![Webhooks menu item](https://mintcdn.com/tyk/_n1j2nedxXfbDX-s/img/2.10/webhooks_menu.png?fit=max\&auto=format\&n=_n1j2nedxXfbDX-s\&q=85\&s=ab67f640336af4fe9b1ac7f03cee2604)

   Click **Add Webhook**.

   ![Add webhook button](https://mintcdn.com/tyk/XYIZ0Oo5nzDVrYaM/img/2.10/add_webhook.png?fit=max\&auto=format\&n=XYIZ0Oo5nzDVrYaM\&q=85\&s=2b35406fa68dc1c6aed19c136fc74ebb)

2. **Configure the webhook**

   Now you need to tell Tyk how and where to send the request. You can include custom headers, for example to inform the target service that the request has come from Tyk - remember to click **ADD** to add the custom header to the configuration.

   ![Add webhook detail](https://mintcdn.com/tyk/_n1j2nedxXfbDX-s/img/2.10/webhook_details.png?fit=max\&auto=format\&n=_n1j2nedxXfbDX-s\&q=85\&s=01aa9f1301e2f8b5bfedba9da751ad65)

   Click **Save** to save it.

***

If you're using Tyk OAS APIs, then you can find details and examples of how to configure webhook event handlers [here](https://tyk.io/docs/api-management/gateway-events.md#webhook-event-handlers-with-tyk-oas-apis).

If you're using Tyk Classic APIs, then you can find details and examples of how to configure webhook event handlers [here](https://tyk.io/docs/api-management/gateway-events.md#webhook-event-handlers-with-tyk-classic-apis).

### Webhook event handlers with Tyk OAS APIs

[Webhooks](https://tyk.io/docs/api-management/gateway-events.md#event-handling-with-webhooks) are event handlers that can be registered against API Events. The webhook will be triggered when the corresponding event is fired and will send a customizable fixed payload to any open endpoint.

Webhooks are configured in the [Tyk OAS API Definition](https://tyk.io/docs/api-management/gateway-config-tyk-oas.md#operation). You can do this via the Tyk Dashboard API or in the API Designer.

If you're using the legacy Tyk Classic APIs, then check out the [Tyk Classic](https://tyk.io/docs/api-management/gateway-events.md#webhook-event-handlers-with-tyk-classic-apis) page.

#### Set up a webhook event handler in the Tyk OAS API Definition

Event handling is configured by adding the `eventHandlers` object to the `server` section of the Tyk OAS Extension (`x-tyk-api-gateway`) in your Tyk OAS API Definition.

The `eventHandlers` object is an array containing configurations for all event handlers registered with the API.

##### Local webhook configuration

When using a local webhook, the event handler element in the `eventHandlers` object has the following configuration which fully declares the webhook behaviour:

* `enabled`: enable the event handler
* `trigger`: the API event that will trigger the webhook
* `type`: the type of event handler, in this case should be set to `webhook`
* `cooldownPeriod`: the [webhook cooldown](https://tyk.io/docs/api-management/gateway-events.md#webhook-cooldown) for duplicate events (in duration format, e.g. 10s, 1m30s); use this to prevent flooding of the target endpoint when multiple events are fired in quick succession
* `name`: a human readable name for the webhook, which will be displayed in Tyk Dashboard
* `url`: this is an **absolute URL** to which the request will be sent
* `method`: this can be any of `GET`, `PUT`, `POST`, `PATCH` or `DELETE` and will be the HTTP method used to send the request; methods that do not support an encoded request body will not have the event metadata provided with the request; we advise using `POST` where possible
* `bodyTemplate`: this is the path to the [webhook template](https://tyk.io/docs/api-management/gateway-events.md#webhook-payload) that will be used to construct the request body
* `headers`: a map of custom headers to be provided with the request

For example:

```json {hl_lines=["18-33"],linenos=true, linenostart=1} theme={null}
{
    "info": {
        "title": "example-local-webhook",
        "version": "1.0.0"
    },
    "openapi": "3.0.3",
    "paths": {},
    "components": {},
    "x-tyk-api-gateway": {
        "info": {
            "name": "example-local-webhook",
            "state": {
                "active": true
            }
        },
        "server": {
            "eventHandlers": [
                {
                    "enabled": true,
                    "trigger": "RatelimitExceeded",
                    "cooldownPeriod": "1s",
                    "type": "webhook",
                    "name": "My local webhook",
                    "url": "https://webhook.site/<unique-target>",
                    "method": "POST",
                    "headers": [
                        {
                        "name": "X-Tyk",
                            "value": "example-local-webhook"
                        }
                    ],
                    "bodyTemplate": "templates/default_webhook.json"
                }
            ],
            "listenPath": {
                "strip": true,
                "value": "/example-local-webhook/"
            }
        },
        "upstream": {
            "rateLimit": {
                "enabled": true,
                "per": "10s",
                "rate": 2
            },
            "url": "http://httpbin.org/"
        }
    }
}
```

In this example a local webhook has been registered to trigger when the `RatelimitExceeded` event is fired. The request rate limit has been set at 2 requests per 10 seconds, so simply make three requests in quick succession to trigger the webhook.

The configuration above is a complete and valid Tyk OAS API Definition that you can import into Tyk to try out the local webhook feature.

Note that to test this you will need to provide a valid target URL for your webhook to send the request; we've used `http://webhook.site`.

##### Global webhook configuration

When using a *global webhook*, the event handler element in the `eventHandlers` object has the following configuration, which references the externally declared webhook using its `id`:

* `enabled`: enable the event handler
* `trigger`: the API event that will trigger the webhook
* `type`: the type of event handler, in this case should be set to `webhook`
* `cooldownPeriod`: the [webhook cooldown](https://tyk.io/docs/api-management/gateway-events.md#webhook-cooldown) for duplicate events (in duration format, e.g. 10s, 1m30s); use this to prevent flooding of the target endpoint when multiple events are fired in quick succession
* `id`: the *webhook id* assigned by Tyk to the global webhook when it was created (this can be determined using the [list webhooks](https://tyk.io/docs/api-reference/webhooks/list-webhooks.md) endpoint in the Tyk Dashboard API)

For example:

```json {hl_lines=["18-24"],linenos=true, linenostart=1} theme={null}
{
    "info": {
        "title": "example-global-webhook",
        "version": "1.0.0"
    },
    "openapi": "3.0.3",
    "paths": {},
    "components": {},
    "x-tyk-api-gateway": {
        "info": {
            "name": "example-global-webhook",
            "state": {
                "active": true
            }
        },
        "server": {
            "eventHandlers": [
                {
                    "enabled": true,
                    "trigger": "RatelimitExceeded",
                    "cooldownPeriod": "1s",
                    "type": "webhook",
                    "id": "<your-global-webhook-id>"
                }
            ],
            "listenPath": {
                "strip": true,
                "value": "/example-global-webhook/"
            }
        },
        "upstream": {
            "rateLimit": {
                "enabled": true,
                "per": "10s",
                "rate": 2
            },
            "url": "http://httpbin.org/"
        }
    }
}
```

In this example a local webhook has been registered to trigger when the `RatelimitExceeded` event is fired. The request rate limit has been set at 2 requests per 10 seconds, so simply make three requests in quick succession to trigger the webhook.

The configuration above is a complete and valid Tyk OAS API Definition that you can import into Tyk to try out the global webhook feature.

Note, however, that to test this you will need to create a *global webhook* in your Tyk Dashboard and replace the value in `id` with the *webhook id* that Tyk Dashboard has allocated to your webhook. You can find this by querying the [list webhooks](https://tyk.io/docs/api-reference/webhooks/list-webhooks.md) endpoint in the Tyk Dashboard API.

> [!NOTE]
>
> When a *global webhook* is registered to a Tyk OAS API, Tyk will create a read-only copy of the webhook [configuration](#local-webhook-configuration) (`url`, `method`, `bodyTemplate`, `headers`) within the API definition. This is so that Tyk Gateway knows how to handle the event, as it does not have access to the store of *global webhooks* registered with Tyk Dashboard.
>
> If the global webhook is subsequently deleted from the Tyk Dashboard, the webhook will automatically be converted to a local webhook in any API definition that was using it.

#### Set up a webhook event handler in the Tyk Dashboard

It is very simple to register webhooks to be triggered in response to specific API events when using Tyk OAS APIs with the Tyk Dashboard. The API Designer in the Dashboard allows you to define *local webhooks* and to register *global webhooks* to handle events.

If you want to use a *global webhook* then you'll need to declare it first, following [these instructions](https://tyk.io/docs/api-management/gateway-events.md#creating-a-global-webhook-definition-using-tyk-dashboard).

1. **Add event handler**

   From the **Settings** tab in the API Designer, scroll down to the **Server** section to find the **Event Handlers** pane. Select **Add Event**.

   ![Add an event handler from the Server section](https://mintcdn.com/tyk/jzHiRUIhvyphWUhc/img/dashboard/api-designer/tyk-oas-webhook-server.png?fit=max\&auto=format\&n=jzHiRUIhvyphWUhc\&q=85\&s=2eae330dc934e49248e4b84845e00aad)

2. **Choose the event to be handled**

   This will add an event handler to the API. You'll need to select which event you want to handle from the drop-down list. Note that currently Tyk OAS only supports webhook event handlers, so this will default to *webhook* type.

   ![Choose the event that will trigger the webhook](https://mintcdn.com/tyk/jzHiRUIhvyphWUhc/img/dashboard/api-designer/tyk-oas-webhook-event-trigger.png?fit=max\&auto=format\&n=jzHiRUIhvyphWUhc\&q=85\&s=81451c62dc83db898745e5aa07506963)

3. **Choose and configure global webhook**

   If you want to use a webhook that you've already registered with Tyk Dashboard, ensure that the **Webhook source** is set to **Global webhook** then select from the drop-down list.

   The only other thing you'll need to configure is the cooldown period.

   ![Select from the list of available global webhooks](https://mintcdn.com/tyk/jzHiRUIhvyphWUhc/img/dashboard/api-designer/tyk-oas-webhook-global.png?fit=max\&auto=format\&n=jzHiRUIhvyphWUhc\&q=85\&s=21aa3dfd66aa7294ecfe198c29f130ac)

   Note that Tyk automatically retrieves the details of the *global webhook* and displays them (read-only) in the API designer.

   ![A fully configured global webhook](https://mintcdn.com/tyk/jzHiRUIhvyphWUhc/img/dashboard/api-designer/tyk-oas-webhook-global-complete.png?fit=max\&auto=format\&n=jzHiRUIhvyphWUhc\&q=85\&s=a900278743eb8c5da13093cda96bc614)

   Don't forget to select **Save API** to apply the changes.

4. **Configure local webhook**

   If you don't want to use a shared *global webhook* but instead want to configure a *local webhook* only available to this API/event then you should ensure that the **Webhook source** is set to **Local webhook**.

   ![Ready to configure a local webhook](https://mintcdn.com/tyk/jzHiRUIhvyphWUhc/img/dashboard/api-designer/tyk-oas-webhook-local.png?fit=max\&auto=format\&n=jzHiRUIhvyphWUhc\&q=85\&s=64c9e5e0f856e1ca92fb5757b48746d3)

   Now you can complete the various fields to set up your *local webhook*. If you want to add custom headers to send with the HTTP request, select **New Header** then enter the header key and value.

   ![A fully configured global webhook](https://mintcdn.com/tyk/jzHiRUIhvyphWUhc/img/dashboard/api-designer/tyk-oas-webhook-local-complete.png?fit=max\&auto=format\&n=jzHiRUIhvyphWUhc\&q=85\&s=cf05fd707023bab69ebc6b635bb968bf)

   Don't forget to select **Save API** to apply the changes.

### Webhook event handlers with Tyk Classic APIs

[Webhooks](https://tyk.io/docs/api-management/gateway-events.md#event-handling-with-webhooks) are event handlers that can
be registered against API Events. The webhook will be triggered when the corresponding event is fired and will send a
customisable fixed payload to any open endpoint.

Webhooks are configured in the Tyk Classic API Definition. You can do this via the Tyk Dashboard API or in the API
Designer.

If you're using the newer Tyk OAS APIs, then check out the [Tyk
OAS](https://tyk.io/docs/api-management/gateway-events.md#webhook-event-handlers-with-tyk-oas-apis)
page.

#### Set up a webhook event handler in the Tyk Classic API Definition

To add a webhook event handler you must add a new event handler object within the `event_handlers.events` section of the
API definition for the appropriate [API event](https://tyk.io/docs/api-management/gateway-events.md#event-types).

The event handler object has the following configuration:

* `handler_name`: this identifies the type of event handler and must be set to `eh_web_hook_handler`
* `handler_meta`: this structure configures the HTTP request that will be sent when the webhook is triggered

The `handler_meta` object has the following configuration:

* `method`: this can be any of `GET`, `PUT`, `POST`, `PATCH` or `DELETE` and will be the HTTP method used to send the
  request; methods that do not support an encoded request body will not have the event metadata provided with the
  request; we advise using `POST` where possible
* `target_path`: this is an **absolute URL** to which the request will be sent
* `template_path`: this is the path to the [webhook
  template](https://tyk.io/docs/api-management/gateway-events.md#webhook-payload) that will be
  used to construct the request body
* `header_map`: a map of custom headers to be provided with the request
* `event_timeout`: the [webhook
  cooldown](https://tyk.io/docs/api-management/gateway-events.md#webhook-cooldown) for duplicate
  events (in seconds); use this to prevent flooding of the target endpoint when multiple events are fired in quick succession

For example:

```json {linenos=true, linenostart=1} theme={null}
{
  "event_handlers": {
    "events": {
      "AuthFailure": [
        {
          "handler_name": "eh_web_hook_handler",
          "handler_meta": {
            "method": "POST",
            "target_path": "http://posttestserver.com/post.php?dir=tyk-event-test",
            "template_path": "templates/default_webhook.json",
            "header_map": { "X-Tyk-Test-Header": "Tyk v1.BANANA" },
            "event_timeout": 10
          }
        }
      ]
    }
  }
}
```

In this example, when the `AuthFailure` event is fired, the webhook event handler will send a request to
`POST http://posttestserver.com/post.php?dir=tyk-event-test` and then start a 10 second cooldown before another webhook
request can be sent.

The request will have one custom header `X-Tyk-Test-Header: Tyk v1.BANANA` and the body will be constructed from the
webhook template located at `templates/default_webhook.json`.

> [!NOTE]
>
> This manually configured webhook event handler is private to the API within which it has been defined, it is not a
> [global
> webhook](https://tyk.io/docs/api-management/gateway-events.md#using-webhooks-with-tyk-dashboard).

#### Set up a webhook event handler in the Tyk Dashboard

It is very simple to register webhooks to be triggered in response to specific API events when using Tyk Classic APIs
with the Tyk Dashboard. The API Designer in the Dashboard allows you to register *global webhooks* to handle events.

Note that Tyk Gateway does not have access to the *global webhook* definitions registered with Tyk Dashboard and can
only operate on the configuration within the API definition. Dashboard will manage the conversion of *global webhooks*
to [locally defined webhook handlers](#set-up-a-webhook-event-handler-in-the-tyk-classic-api-definition) within the Tyk
Classic API definition, automatically updating the configuration in each API definition when the APIs are reloaded to
the Gateway.

1. **Define the webhook**

   Before you can configure a webhook event handler for your API, you must first create a global webhook from the
   **Webhooks** screen in the **API Management** menu, as described
   [here](https://tyk.io/docs/api-management/gateway-events.md#creating-a-global-webhook-definition-using-tyk-dashboard).

2. **Register the webhook with the event**

   From the API Designer select the **Advanced Options** tab and locate the **Webhooks** panel:

   ![Webhook API Details](https://mintcdn.com/tyk/_n1j2nedxXfbDX-s/img/2.10/webhooks_designer_settings.png?fit=max\&auto=format\&n=_n1j2nedxXfbDX-s\&q=85\&s=f9e463ae63e49fbd72365a85b8465bb7)

   Now:

   * select the *API Event* for which you want to trigger the webhook from the dropdown list
   * select the *Webhook to use* when the event fires, again from the dropdown list
   * finally, configure the required *Cooldown period*
   * click **Add**

   Note that you can register multiple webhooks to be triggered in response to a single event and you can register the same
   webhook with multiple API events.

   Remember to click **Save** to save your changes.

#### Set up a webhook event handler in Tyk Operator

Tyk Operator supports event handler integration for Tyk Classic API Definition. Configuring the `event_handlers` field
in ApiDefinition Custom Resource Definition (CRD) enables webhooks to be triggered by [specific
API events](https://tyk.io/docs/api-management/gateway-events.md#event-types).

The process for configuring webhook event handlers using Tyk Operator is similar to that explained in
[Set up a webhook event handler in the Tyk Classic API Definition](#set-up-a-webhook-event-handler-in-the-tyk-classic-api-definition).
The example API Definition below enables the event handler by setting `spec.event_handlers`.

```yaml {hl_lines=["14-25"],linenos=true, linenostart=1} theme={null}
apiVersion: tyk.tyk.io/v1alpha1
kind: ApiDefinition
metadata:
  name: webhook-handler
spec:
  name: webhook-handler
  use_keyless: true
  protocol: http
  active: true
  proxy:
    target_url: http://httpbin.org
    listen_path: /webhook-handler
    strip_listen_path: true
  event_handlers:
    events:
      AuthFailure:
        - handler_name: "eh_web_hook_handler"
          handler_meta:
            method: "POST"
            name: "webhook name"
            target_path: "http://posttestserver.com/post.php?dir=tyk-event-test"
            template_path: "templates/default_webhook.json"
            header_map:
              X-Tyk-Test-Header: "Tyk v1.BANANA"
            event_timeout: 10
```

## Logging API events

Tyk’s built-in logging event handler is designed primarily for debugging purposes and will store details of an API event to the configured logger output.

The Tyk platform can be configured to log at various verbosity levels (info, debug, warn, error) and can be integrated with third-party log aggregation tools like Sentry, Logstash, Graylog, and Syslog. For full details on configuring the Tyk logger, see [this section](https://tyk.io/docs/api-management/logs/application-logs.md).

> [!NOTE]
>
> Logging event handlers are currently only supported by Tyk Classic APIs.

### Configuring the event handler

Registering a logging event handler to your Tyk Classic API is the same as adding any other event handler, within the `event_handlers` section of the API definition.

The `handler_name` for the logging event handler should be set to: `eh_log_handler`.

The `handler_meta` for the logging event handler contains a single field:

* `prefix` is a label that will be prepended to each log entry

For example, to register event handlers to log the `AuthFailure` and `KeyExpired` events you might add the following to your API definition:

```json theme={null}
{
  "event_handlers": {
    "events": {
      "AuthFailure": [
        {
          "handler_name": "eh_log_handler",
          "handler_meta": {
            "prefix": "AuthFailureEvent"
          }
        }
      ],
      "KeyExpired": [
        {
          "handler_name": "eh_log_handler",
          "handler_meta": {
            "prefix": "KeyExpiredEvent"
          }
        }
      ]
    }
  }
}
```

In this example

* the `AuthFailure` event will trigger the event handler to generate a log with the prefix `AuthFailureEvent`
* the `KeyExpired` event will trigger the event handler to generate a log with the prefix `KeyExpiredEvent`

When the event handler is triggered an entry will be made in the log containing the corresponding prefix, which can be useful for monitoring and debugging purposes.

## Custom API event handlers

Tyk supports you to script your own custom code in JavaScript (JS) that will be invoked in response to API events. This is executed asynchronously so you don't need to worry about it blocking the Gateway handling requests. Event handlers like this can be very powerful for automating session, user and API-level functions.

It is important to note that unlike custom JavaScript [plugins](https://tyk.io/docs/api-management/plugins/javascript.md#), custom event handlers execute in a *global* JavaScript environment. This means that you need to be careful when naming the event handlers: if you use the same event handler name for different event handling code across two APIs, only one of them will execute, as the other will be overridden when loaded.

Custom event handlers have access to the [JavaScript API](https://tyk.io/docs/api-management/plugins/javascript.md#javascript-api) which gives access to the session object and enables your code to make HTTP calls. This is particularly useful if you want to interface with another API with a complex request/response cycle.

> [!NOTE]
>
> Custom event handlers are currently only supported by Tyk Classic APIs.

### Creating a custom event handler

A custom event handler consists of a function that accepts two variables (`event` and `context`) and has no return value.

Creating an event handler is very similar to [creating custom JS plugins](https://tyk.io/docs/api-management/plugins/javascript.md#using-javascript-with-tyk), simply invoke the correct constructors with a closure in the TykJS namespace:

```js theme={null}
// ---- Sample custom event handler -----
var sampleHandler = new TykJS.TykEventHandlers.NewEventHandler({});

sampleHandler.NewHandler(function(event, context) {
  // You can log to Tyk console output by calling the built-in log() function:
  log("This handler does nothing, but this will appear in your terminal")

  return
});
```

#### The `event` object

This contains the [event metadata](https://tyk.io/docs/api-management/gateway-events.md#event-metadata) in the following structure:

```json theme={null}
{
  "Type": "Event Type Code",
  "Meta": {
    "Message": "My Event Description",
    "OriginatingRequest": "Base64-encoded request",
    "Path": "/{{api_id}}/{{path}}",
    "Origin": "1.1.1.1",
    "Key": "{{Auth Key}}"
  },
  "TimeStamp": "2024-01-01 23:59:59.111157073 +0000 UTC"
}
```

The fields in `Meta` depend on the event type. For the fields of each event, see [Specific Event Metadata](https://tyk.io/docs/api-management/gateway-events.md#specific-event-metadata).

#### The `context` Variable

Tyk injects a `context` object into your event handler giving access to more information about the request. This object has the following structure:

```js theme={null}
type JSVMContextGlobal struct {
  APIID string
  OrgID string
}
```

It is populated with the API ID and Org ID of the request that your custom function can use together with the `event` metadata to interact with the Tyk REST API functions, for example:

```js theme={null}
// Use the TykGetKeyData function to retrieve a session from the session store, use the context variable to give the APIID for the key.
var thisSession = JSON.parse(TykGetKeyData(event.Meta.Key, context.APIID))
log("Expires: " + thisSession.expires)
```

### Registering a custom event handler

Registering a custom event handler to your Tyk Classic API is the same as adding any other event handler, within the `event_handlers` section of the API definition.

The `handler_name` for a custom event handler should be set to: `eh_dynamic_handler`.

The `handler_meta` for a custom event handler consists of two fields:

* `name` is the unique name of your middleware object
* `path` is the relative path to the file (it can be absolute)

For example, to register a custom event handler with the name `sessionHandler` to be invoked in response to the `KeyExpired` event you would add the following to your API definition:

```json theme={null}
{
  "event_handlers": {
    "events": {
      "KeyExpired": [
        {
          "handler_name":"eh_dynamic_handler",
          "handler_meta": {
            "name": "sessionHandler",
            "path": "event_handlers/session_editor.js"
          }
        }
      ]
    }
  }
}
```

### Loading custom event handlers

The JavaScript files are loaded on API reload into the global JSVM. If a hot-reload event occurs, the global JSVM is re-set and files are re-loaded. This could cause event handlers that are currently executing to get abandoned. This is a measured risk and should not cause instability, however it should be noted that because of this, in an environment where reloads occur frequently, there is risk that event handler may not fire correctly.

## Monitoring quota consumption

Tyk provides the ability to actively monitor both user and organization quotas, using a dedicated webhook to notify your stakeholders, your system stack or the requesting API client when certain thresholds have been reached for a token.

Unlike API event [webhooks](https://tyk.io/docs/api-management/gateway-events.md#event-handling-with-webhooks) the quota monitor is configured at the Gateway level.

> [!NOTE]
>
> Advanced quota threshold monitoring is currently only supported by Tyk Classic APIs.

### Configuring the quota consumption monitor

To enable advanced quota monitoring you will need to add a new `monitor` section to your Tyk Gateway configuration file (`tyk.conf`).

This has the following fields:

* `enable_trigger_monitors`: set to `true` to have the monitors start to measure quota thresholds
* `configuration`: a [webhook configuration](https://tyk.io/docs/api-management/gateway-events.md#event-handling-with-webhooks) object
* `global_trigger_limit`: this is a percentage of the quota that the key must consume for the webhook to be fired
* `monitor_user_keys`: set to `true` to monitor individual tokens (this may result in a large number of triggers as it scales with the number of user tokens that are issued)
* `monitor_org_keys`: set to `true` to monitor organization quotas

For example:

```json theme={null}
{
  "monitor": {
    "enable_trigger_monitors": true,
    "configuration": {
      "method": "POST",
      "target_path": "http://posttestserver.com/post.php?dir=tyk-monitor-drop",
      "template_path": "templates/monitor_template.json",
      "header_map": {"x-tyk-monitor-secret": "12345"},
      "event_timeout": 10
    },
    "global_trigger_limit": 80.0,
    "monitor_user_keys": false,
    "monitor_org_keys": true
  }
}
```

With this configuration, a monitor is configured to issue a request to `POST http://posttestserver.com/post.php?dir=tyk-monitor-drop` when 80% of the API-level quota has been consumed. This request will have the `x-tyk-monitor-secret` header (set to a value of `12345`) and will provide the content of the template file found at `templates/monitor_template.json` in the request body. A minimum of 10 seconds will elapse between successive monitor webhooks being fired.

> [!NOTE]
>
> If you are using our [Classic Developer Portal](https://tyk.io/docs/tyk-developer-portal/tyk-portal-classic/portal-events-notifications.md), developers registered in the portal will also receive emails about quota threshold limits being reached.

#### Setting advanced thresholds

The default quota consumption monitor will be triggered at the same level of quota usage for all users. Sometimes you might want to have a more granular approach with different triggering thresholds per user or organization. Sometimes you might want to fire the event at multiple thresholds, for example when the user hits 50%, 75% and 90% of their allowed quota.

You can set user specific trigger levels for a user by additionally adding a `monitor` section to the Key's [Session](https://tyk.io/docs/api-management/access-control/sessions-and-keys/understanding-sessions.md). This has one field, which is an array of `trigger_limits` (thresholds) that must be in *descending* order and represent the percentage of the quota that must be reached in order for the trigger to be fired, for example:

```yaml theme={null}
"monitor": {
  "trigger_limits": [90.0, 75.0, 50.0]
}
```

If this is included in the session object, then the quota threshold event will be fired and the monitor webhook triggered when the user hits 50%, then 75%, and then again at 90% consumption.

You can configure advanced thresholds for all users in an organization by adding the `monitor` section to the organization session object.

### Webhook payload

When the quota consumption monitor is fired, the webhook request that is issued will have the following payload:

```json theme={null}
{
  "event": "TriggerExceeded",
  "message": "Quota trigger reached",
  "org": "53ac07777cbb8c2d53000002",
  "key": "",
  "trigger_limit": "80",
}
```

* `trigger_limit` will indicate which threshold has been reached (as defined in the session object's `monitor` section).
* `org` will contain the OrgID for the user or organization that triggered the event
* `key` will contain the *raw API key* used in the request only if the event was triggered by a user quota

*Note: if the webhook was triggered by an organization threshold, `key` will be blank.*

> [!WARNING]
>
> When the monitor is triggered by a user hitting their quota threshold, the **raw API key** is provided in the webhook payload. It is important to secure the webhook endpoint and to handle the payload securely on the receiving end.
