Webhook (HTTP POST 2, post2)
Same idea as the simple HTTP POST webhook, but post2 lets you use Jinja2 in http_post2_payload and http_post2_headers so values can reference fields from the match (including nested keys via _data and jinja_root_name).
In YAML key/value form, prefer single quotes around values that contain Jinja so parsing stays predictable.
Options walks through each post2 key; Full working example at the bottom is a complete rule that shows Jinja in the payload and headers.
Options
Keys below match the ElastAlert 2 alerter. Shared rule fields such as alert_subject apply as described in Subject & body. Example fragments from the ElastAlert 2 reference appear indented under the option they illustrate (add your own name, type, index, and filter to make a full rule).
Required
http_post2_url— The URL to POST.
Incorrect usage with double quotes
alert: post2
http_post2_url: "http://example.com/api"
http_post2_payload:
# this will result in an error as " is escaped to \"
description: 'hello {{ _data["name"] }}'
# this will result in an error as " is escaped to \"
state: '{{ ["low","medium","high","critical"][event.severity] }}'
http_post2_headers:
authorization: Basic 123dr3234
X-custom-type: '{{type}}'Correct usage with single quotes
alert: post2
http_post2_url: "http://example.com/api"
http_post2_payload:
description: hello {{ _data['name'] }}
state: "{{ ['low','medium','high','critical'][event.severity] }}"
http_post2_headers:
authorization: Basic 123dr3234
X-custom-type: '{{type}}'Example usage
alert: post2
http_post2_url: "http://example.com/api"
http_post2_payload:
description: "An event came from IP {{clientip}}"
username: "{{user.name}}"
http_post2_raw_fields:
ip: clientip
http_post2_headers:
authorization: Basic 123dr3234
X-custom-type: '{{type}}'Example usage with json string formatting
alert: post2
jinja_root_name: _new_root
http_post2_url: "http://example.com/api"
http_post2_payload: |
{
"description": "An event came from IP {{ _new_root["client.ip"] }}",
"username": "{{ _new_root['username'] }}"
{%- for k, v in some_field.items() -%}
,"{{ k }}": "changed_{{ v }}"
{%- endfor -%}
}
http_post2_raw_fields:
ip: clientip
http_post2_headers: |
{
"authorization": "Basic 123dr3234",
"X-custom-{{key}}": "{{type}}"
}Optional
-
http_post2_payload— A JSON string or list of key:value pairs to use for the HTTP POST payload. You can use{{ field }}(Jinja2 template) in both keys and values to reference any field in matched events (including nested ES fields and nested payload keys). If not defined, all Elasticsearch keys are sent. Example:"description_{{ my_field }}": "Type: {{ type }}\nSubject: {{ title }}". When field names use dot notation or reserved characters,_datacan be used to access them. If_dataconflicts with your top-level data, usejinja_root_nameto change its name. -
http_post2_raw_fields— List of key:value pairs to use as POST content. Example:ip: clientipmaps theclientipElasticsearch field to the JSON keyip. This field overwrites keys with the same name inhttp_post2_payload. -
http_post2_headers— A JSON string or list of key:value pairs to use as HTTP POST headers. You can use{{ field }}(Jinja2 template) in both keys and values to reference matched-event fields (including nested fields). Example:"Authorization": "{{ user }}". Headers"Content-Type": "application/json"and"Accept": "application/json;charset=utf-8"are present by default; override them only if needed. When field names use dot notation or reserved characters,_datacan be used to access them. If_dataconflicts with your top-level data, usejinja_root_nameto change its name. -
http_post2_proxy— Proxy URL, if required. Only HTTPS is supported. -
http_post2_all_values— Boolean of whether or not to include every key value pair from the match in addition to those in http_post2_payload and http_post2_static_payload. Defaults to True if http_post2_payload is not specified, otherwise False. -
http_post2_timeout— The timeout value, in seconds, for making the post. The default is 10. If a timeout occurs, the alert will be retried next time elastalert cycles. -
http_post2_ca_certs— Set this option toTrueor a path to a CA cert bundle or directory (eg:/etc/ssl/certs/ca-certificates.crt) to validate the SSL certificate. -
http_post2_ignore_ssl_errors— By default ElastAlert 2 verifies the TLS certificate. Set toTrueto skip verification. Note: Disabling verification exposes the rule to man-in-the-middle risk on untrusted networks—use only for debugging or when you explicitly trust the endpoint (for example a private CA you control).
Full working example
name: Example custom webhook (HTTP POST 2)
type: any
index: "*-*"
filter:
- query:
query_string:
query: "level:error OR log.level:error"
alert:
- "post2"
http_post2_url: "https://your-service.example/hooks/elastalert"
http_post2_payload:
source: logit
summary: "Error from ElastAlert rule"
http_post2_raw_fields:
host: host.name
http_post2_headers:
Content-Type: application/jsonUse Jinja in payload or header values when you need match data, for example summary: '{{ host.name }}' or keys like description_{{ type }} (see ElastAlert 2 rules for quoting).