1# REST API <a id="icinga2-api"></a>
2
3* [Setup](12-icinga2-api.md#icinga2-api-setup)
4* [Introduction](12-icinga2-api.md#icinga2-api-introduction)
5* Endpoints
6    * [Config Objects](12-icinga2-api.md#icinga2-api-config-objects)
7    * [Actions](12-icinga2-api.md#icinga2-api-actions)
8    * [Event Streams](12-icinga2-api.md#icinga2-api-event-streams)
9    * [Status and Statistics](12-icinga2-api.md#icinga2-api-status)
10    * [Config Management](12-icinga2-api.md#icinga2-api-config-management)
11    * [Types](12-icinga2-api.md#icinga2-api-types)
12    * [Templates](12-icinga2-api.md#icinga2-api-config-templates)
13    * [Variables](12-icinga2-api.md#icinga2-api-variables)
14    * [Debug Console](12-icinga2-api.md#icinga2-api-console)
15* [API Clients](12-icinga2-api.md#icinga2-api-clients)
16    * [Programmatic Examples](12-icinga2-api.md#icinga2-api-clients-programmatic-examples)
17
18
19## Setting up the API <a id="icinga2-api-setup"></a>
20
21You can run the CLI command `icinga2 api setup` to enable the
22`api` [feature](11-cli-commands.md#enable-features) and set up
23certificates as well as a new API user `root` with an auto-generated password in the
24`/etc/icinga2/conf.d/api-users.conf` configuration file:
25
26```bash
27icinga2 api setup
28```
29
30Make sure to restart Icinga 2 to enable the changes you just made:
31
32```bash
33systemctl restart icinga2
34```
35
36If you prefer to set up the API manually, you will have to perform the following steps:
37
38* Set up X.509 TLS certificates for Icinga 2
39* Enable the `api` feature (`icinga2 feature enable api`)
40* Create an `ApiUser` object for authentication
41
42The next chapter provides a quick overview of how you can use the API.
43
44## Introduction <a id="icinga2-api-introduction"></a>
45
46The Icinga 2 API allows you to manage configuration objects
47and resources in a simple, programmatic way using HTTP requests.
48
49The URL endpoints are logically separated allowing you to easily
50make calls to
51
52* query, create, modify and delete [config objects](12-icinga2-api.md#icinga2-api-config-objects)
53* perform [actions](12-icinga2-api.md#icinga2-api-actions) (reschedule checks, etc.)
54* subscribe to [event streams](12-icinga2-api.md#icinga2-api-event-streams)
55* [manage configuration packages](12-icinga2-api.md#icinga2-api-config-management)
56* evaluate [script expressions](12-icinga2-api.md#icinga2-api-console)
57
58### Requests <a id="icinga2-api-requests"></a>
59
60Any tool capable of making HTTP requests can communicate with
61the API, for example [curl](https://curl.haxx.se/).
62
63Requests are only allowed to use the HTTPS protocol so that
64traffic remains encrypted.
65
66By default the Icinga 2 API listens on port `5665` which is shared with
67the cluster stack. The port can be changed by setting the `bind_port` attribute
68for the [ApiListener](09-object-types.md#objecttype-apilistener)
69object in the `/etc/icinga2/features-available/api.conf`
70configuration file.
71
72Supported request methods:
73
74  Method | Usage
75  -------|--------
76  GET    | Retrieve information about configuration objects. Any request using the GET method is read-only and does not affect any objects.
77  POST   | Update attributes of a specified configuration object.
78  PUT    | Create a new object. The PUT request must include all attributes required to create a new object.
79  DELETE | Remove an object created by the API. The DELETE method is idempotent and does not require any check if the object actually exists.
80
81All requests except `GET` require the following `Accept` header:
82
83```
84Accept: application/json
85```
86
87Each URL is prefixed with the API version (currently "/v1").
88
89HTTP header size is limited to 8KB per request.
90
91### Responses <a id="icinga2-api-responses"></a>
92
93Successful requests will send back a response body containing a `results`
94list. Depending on the number of affected objects in your request, the
95`results` list may contain more than one entry.
96
97The output will be sent back as a JSON object:
98
99```json
100{
101    "results": [
102        {
103            "code": 200.0,
104            "status": "Object was created."
105        }
106    ]
107}
108```
109
110> **Tip**
111>
112> You can use the [pretty](12-icinga2-api.md#icinga2-api-parameters-global) parameter to beautify the JSON response.
113
114You can also use [jq](https://stedolan.github.io/jq/) or `python -m json.tool`
115in combination with curl on the CLI.
116
117```bash
118curl ... | jq
119curl ... | python -m json.tool
120```
121
122jq also has additional filter capabilities, as shown in [this blogpost](https://www.netways.de/blog/2018/08/24/json-in-bequem/).
123
124```bash
125curl ... |jq '{name: .results[].name}'
126```
127
128For programmatic examples in various languages, check the chapter
129[below](12-icinga2-api.md#icinga2-api-clients).
130
131> **Note**
132>
133> Future versions of Icinga 2 might set additional fields. Your application
134> should gracefully handle fields it is not familiar with, for example by
135> ignoring them.
136
137### HTTP Statuses <a id="icinga2-api-http-statuses"></a>
138
139The API will return standard [HTTP statuses](https://www.ietf.org/rfc/rfc2616.txt)
140including error codes.
141
142When an error occurs, the response body will contain additional information
143about the problem and its source. Set `verbose` to true to retrieve more
144insights into what may be causing the error.
145
146A status code between 200 and 299 generally means that the request was
147successful.
148
149Return codes within the 400 range indicate that there was a problem with the
150request. Either you did not authenticate correctly, you are missing the authorization
151for your requested action, the requested object does not exist or the request
152was malformed.
153
154A status in the range of 500 generally means that there was a server-side problem
155and Icinga 2 is unable to process your request.
156
157### Security <a id="icinga2-api-security"></a>
158
159* HTTPS only.
160* TLS v1.2+ is required.
161* TLS cipher lists are hardened [by default](09-object-types.md#objecttype-apilistener).
162* Authentication is [required](12-icinga2-api.md#icinga2-api-authentication).
163
164### Authentication <a id="icinga2-api-authentication"></a>
165
166There are two different ways for authenticating against the Icinga 2 API:
167
168* Username and password using HTTP basic auth
169* X.509 client certificate
170
171In order to configure a new API user you'll need to add a new [ApiUser](09-object-types.md#objecttype-apiuser)
172configuration object. In this example `root` will be the basic auth username
173and the `password` attribute contains the basic auth password.
174
175```
176# vim /etc/icinga2/conf.d/api-users.conf
177
178object ApiUser "root" {
179  password = "icinga"
180}
181```
182
183Alternatively you can use X.509 client certificates by specifying the `client_cn`
184the API should trust. The X.509 certificate has to be signed by the CA certificate
185that is configured in the [ApiListener](09-object-types.md#objecttype-apilistener) object.
186
187```
188# vim /etc/icinga2/conf.d/api-users.conf
189
190object ApiUser "root" {
191  client_cn = "CertificateCommonName"
192}
193```
194
195An `ApiUser` object can have both authentication methods configured.
196
197#### Authentication Test <a id="icinga2-api-authentication-test"></a>
198
199You can test authentication by sending a GET request to the API:
200
201```bash
202curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1'
203```
204
205In case you get an error message make sure to check the API user credentials.
206
207When using client certificates for authentication you'll need to pass your client certificate
208and private key to the curl call:
209
210```bash
211curl -k --cert example.localdomain.crt --key example.localdomain.key 'https://example.localdomain:5665/v1/status'
212```
213
214In case of an error make sure to verify the client certificate and CA.
215
216The curl parameter `-k` disables certificate verification and should therefore
217only be used for testing. In order to securely check each connection you'll need to
218specify the trusted CA certificate using the curl parameter`--cacert`:
219
220```bash
221curl -u root:icinga --cacert ca.crt 'icinga2.node1.localdomain:5665/v1'
222```
223
224Read the next chapter on [API permissions](12-icinga2-api.md#icinga2-api-permissions)
225in order to configure authorization settings for your newly created API user.
226
227### Permissions <a id="icinga2-api-permissions"></a>
228
229By default an API user does not have any permissions to perform
230actions on the URL endpoints.
231
232Permissions for API users must be specified in the `permissions` attribute
233as array. The array items can be a list of permission strings with wildcard
234matches. Please notice, that the permission system that is used by the API differs from the permission system used by the Icinga Web 2 frontend or other parts of Icinga 2.
235
236The permission system mainly relies on the url scheme of the API endpoints (See listing below).
237
238Example for an API user with all permissions:
239
240```
241permissions = [ "*" ]
242```
243
244Note that you can use wildcards to include all possible hierarchically lower items. Here's another example that only allows the user
245to perform read-only object queries for hosts and services:
246
247```
248permissions = [ "objects/query/Host", "objects/query/Service" ]
249```
250
251You can also further restrict permissions by specifying a filter expression. The
252filter expression has to be a [lambda function](17-language-reference.md#nullary-lambdas)
253which must return a boolean value.
254
255The following example allows the API user to query all hosts and services which have a
256custom variable `os` that matches the regular expression `^Linux`.
257The [regex function](18-library-reference.md#global-functions-regex) is available as global function.
258
259```
260permissions = [
261  {
262    permission = "objects/query/Host"
263    filter = {{ regex("^Linux", host.vars.os) }}
264  },
265  {
266    permission = "objects/query/Service"
267    filter = {{ regex("^Linux", service.vars.os) }}
268  }
269]
270```
271
272More information about filters can be found in the [filters](12-icinga2-api.md#icinga2-api-filters) chapter.
273
274Prior to setting complex permissions, ensure to always [test](12-icinga2-api.md#icinga2-api-authentication-test)
275them step by step.
276
277
278#### Overview <a id="icinga2-api-permissions-overview"></a>
279
280Permissions are tied to a maximum HTTP request size to prevent abuse, responses sent by Icinga are not limited.
281An API user with all permissions ("\*") may send up to 512 MB regardless of the endpoint.
282
283Available permissions for specific URL endpoints:
284
285  Permissions                   | URL Endpoint  | Supports filters  | Max body size in MB
286  ------------------------------|---------------|-------------------|---------------------
287  actions/&lt;action&gt;        | /v1/actions   | Yes               | 1
288  config/query                  | /v1/config    | No                | 1
289  config/modify                 | /v1/config    | No                | 512
290  console                       | /v1/console   | No                | 1
291  events/&lt;type&gt;           | /v1/events    | No                | 1
292  objects/query/&lt;type&gt;    | /v1/objects   | Yes               | 1
293  objects/create/&lt;type&gt;   | /v1/objects   | No                | 1
294  objects/modify/&lt;type&gt;   | /v1/objects   | Yes               | 1
295  objects/delete/&lt;type&gt;   | /v1/objects   | Yes               | 1
296  status/query                  | /v1/status    | Yes               | 1
297  templates/&lt;type&gt;        | /v1/templates | Yes               | 1
298  types                         | /v1/types     | Yes               | 1
299  variables                     | /v1/variables | Yes               | 1
300
301The required actions or types can be replaced by using a wildcard match ("\*").
302
303
304### Parameters <a id="icinga2-api-parameters"></a>
305
306Depending on the request method there are two ways of passing parameters to the request:
307
308* JSON object as request body (all request methods other than `GET`)
309* Query string as URL parameter (all request methods)
310
311Reserved characters by the HTTP protocol must be [URL-encoded](https://en.wikipedia.org/wiki/Percent-encoding)
312as query string, e.g. a space character becomes `%20`.
313
314Example for a URL-encoded query string:
315
316```
317/v1/objects/hosts?filter=match(%22example.localdomain*%22,host.name)&attrs=name&attrs=state
318```
319
320Here are the exact same query parameters as a JSON object:
321
322```json
323{ "filter": "match(\"example.localdomain*\",host.name)", "attrs": [ "host.name", "host.state" ] }
324```
325
326The [match function](18-library-reference.md#global-functions-match) is available as global function
327in Icinga 2.
328
329Whenever filters and other URL parameters don't work due to encoding issues,
330consider passing them in the request body. For GET requests, this method is explained
331[here](12-icinga2-api.md#icinga2-api-requests-method-override).
332
333You can use [jo](https://github.com/jpmens/jo) to format JSON strings on the shell. An example
334for API actions shown [here](12-icinga2-api.md#icinga2-api-actions-unix-timestamps).
335
336
337### Global Parameters <a id="icinga2-api-parameters-global"></a>
338
339Name            | Description
340----------------|--------------------
341pretty          | Pretty-print the JSON response.
342verbose         | Add verbose debug information inside the `diagnostic_information` key into the response if available. This helps with troubleshooting failing requests.
343
344Example as URL parameter:
345
346```
347/v1/objects/hosts?pretty=1
348```
349
350Example as JSON object:
351
352```json
353{ "pretty": true }
354```
355
356### Request Method Override <a id="icinga2-api-requests-method-override"></a>
357
358`GET` requests do not allow you to send a request body. In case you cannot pass everything as URL
359parameters (e.g. complex filters or JSON-encoded dictionaries) you can use the `X-HTTP-Method-Override`
360header. This comes in handy when you are using HTTP proxies disallowing `PUT` or `DELETE` requests too.
361
362Query an existing object by sending a `POST` request with `X-HTTP-Method-Override: GET` as request header:
363
364```bash
365curl -k -s -S -i -u 'root:icinga' -H 'Accept: application/json' \
366 -H 'X-HTTP-Method-Override: GET' -X POST \
367 'https://localhost:5665/v1/objects/hosts'
368```
369
370Delete an existing object by sending a `POST` request with `X-HTTP-Method-Override: DELETE` as request header:
371
372```bash
373curl -k -s -S -i -u 'root:icinga' -H 'Accept: application/json' \
374 -H 'X-HTTP-Method-Override: DELETE' -X POST \
375 'https://localhost:5665/v1/objects/hosts/example.localdomain'
376```
377
378Query objects with complex filters. For a detailed introduction into filter, please
379read the [following chapter](12-icinga2-api.md#icinga2-api-filters).
380
381```bash
382curl -k -s -S -i -u 'root:icinga' -H 'Accept: application/json' \
383 -H 'X-HTTP-Method-Override: GET' -X POST \
384 'https://localhost:5665/v1/objects/services' \
385 -d '{ "filter": "service.state==2 && match(\"ping*\",service.name)" }'
386```
387
388### Filters <a id="icinga2-api-filters"></a>
389
390#### Simple Filters <a id="icinga2-api-simple-filters"></a>
391
392By default actions and queries operate on all objects unless further restricted by the user. For
393example, the following query returns all `Host` objects:
394
395```
396https://localhost:5665/v1/objects/hosts
397```
398
399If you're only interested in a single object, you can limit the output to that object by specifying its name:
400
401```
402https://localhost:5665/v1/objects/hosts?host=localhost
403```
404
405**The name of the URL parameter is the lower-case version of the type the query applies to.** For
406example, for `Host` objects the URL parameter therefore is `host`, for `Service` objects it is
407`service` and so on.
408
409You can also specify multiple objects:
410
411```
412https://localhost:5665/v1/objects/hosts?hosts=first-host&hosts=second-host
413```
414
415Again -- like in the previous example -- the name of the URL parameter is the lower-case version of the type. However, because we're specifying multiple objects here the **plural form** of the type is used.
416
417When specifying names for objects which have composite names like for example services the
418full name has to be used:
419
420```
421https://localhost:5665/v1/objects/services?service=localhost!ping6
422```
423
424The full name of an object can be obtained by looking at the `__name` attribute.
425
426#### Advanced Filters <a id="icinga2-api-advanced-filters"></a>
427
428Most of the information provided in this chapter applies to both permission filters (as used when
429configuring `ApiUser` objects) and filters specified in queries.
430
431Advanced filters allow users to filter objects using lambda expressions.
432The syntax for these filters is the same like for [apply rule expressions](03-monitoring-basics.md#using-apply-expressions).
433
434The `filter` parameter can only be specified once, complex filters must
435be defined once in the provided string value.
436
437> **Note**
438>
439> Filters used as URL parameter must be URL-encoded. The following examples
440> are **not URL-encoded** for better readability.
441
442Example matching all services in NOT-OK state:
443
444```
445https://localhost:5665/v1/objects/services?filter=service.state!=ServiceOK
446```
447
448Example [matching](18-library-reference.md#global-functions-match) all hosts by a name string pattern:
449
450```
451https://localhost:5665/v1/objects/hosts?filter=match("example.localdomain*",host.name)
452```
453
454Example for all hosts which are in the host group `linux-servers`:
455```
456https://localhost:5665/v1/objects/hosts?filter="linux-servers" in host.groups
457```
458
459> **Tip**
460>
461> Best practice for filters is to use [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override)
462> for GET requests and always pass them in the request body.
463
464User-specified filters are run in a sandbox environment which ensures that filters cannot
465modify Icinga's state, for example object attributes or global variables.
466
467When querying objects of a specific type the filter expression is evaluated for each object
468of that type. The object is made available to the filter expression as a variable whose name
469is the lower-case version of the object's type name.
470
471For example when querying objects of type `Host` the variable in the filter expression is named
472`host`. Additionally related objects such as the host's check command are also made available
473(e.g., via the `check_command` variable). The variable names are the exact same as for the `joins`
474query parameter; see [object query joins](12-icinga2-api.md#icinga2-api-config-objects-query-joins)
475for details.
476
477The object is also made available via the `obj` variable. This makes it easier to build
478filters which can be used for more than one object type (e.g., for permissions).
479
480Some queries can be performed for more than just one object type. One example is the 'reschedule-check'
481action which can be used for both hosts and services. When using advanced filters you will also have to specify the
482type using the `type` parameter:
483
484```bash
485curl -k -s -S -i -u root:icinga -H 'Accept: application/json' -X POST \
486 'https://localhost:5665/v1/actions/reschedule-check' \
487 -d '{ "type": "Service", "filter": "service.name==\"ping6\"", "pretty": true }'
488```
489
490##### Filter Variables <a id="icinga2-api-advanced-filters-variables"></a>
491
492Filter values need to be escaped in the same way as in the Icinga 2 DSL.
493
494The example below is not valid:
495
496```
497-d '{ "type": "Host", "filter": ""linux-servers" in host.groups" }'
498```
499
500The double quotes need to be escaped with a preceeding backslash:
501
502```
503-d '{ "type": "Host", "filter": "\"linux-servers\" in host.groups" }'
504```
505
506You can use the `filter_vars` attribute to avoid additional escaping.
507This follows the same principle as with parameter binding known from RDBMS.
508Specify a placeholder variable inside the `filter` string, and actually
509assign its value inside the `filter_vars` dictionary.
510
511That way you can also keep the `filter` string the same for different
512requests with only changing the `filter_vars`.
513
514```bash
515curl -k -s -S -i -u 'root:icinga' -H 'Accept: application/json' \
516 -H 'X-HTTP-Method-Override: GET' -X POST \
517 'https://localhost:5665/v1/objects/hosts' \
518 -d '{ "filter": "group in host.groups", "filter_vars": { "group": "linux-servers" }, "pretty": true }'
519```
520
521We're using [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override) here because
522the HTTP specification does not allow message bodies for GET requests.
523
524The `filters_vars` attribute can only be used inside the request body, but not as
525a URL parameter because there is no way to specify a dictionary in a URL.
526
527The example from [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override)
528can be enhanced to avoid additional parameter value escaping.
529
530```bash
531curl -k -s -S -i -u 'root:icinga' -H 'Accept: application/json' \
532 -H 'X-HTTP-Method-Override: GET' -X POST \
533 'https://localhost:5665/v1/objects/services' \
534 -d '{ "filter": "service.state==state && match(pattern,service.name)", "filter_vars": { "state": 2, "pattern": "ping*" } }'
535```
536
537## Config Objects <a id="icinga2-api-config-objects"></a>
538
539Provides methods to manage configuration objects:
540
541* [creating objects](12-icinga2-api.md#icinga2-api-config-objects-create)
542* [querying objects](12-icinga2-api.md#icinga2-api-config-objects-query)
543* [modifying objects](12-icinga2-api.md#icinga2-api-config-objects-modify)
544* [deleting objects](12-icinga2-api.md#icinga2-api-config-objects-delete)
545
546### API Objects and Cluster Config Sync <a id="icinga2-api-config-objects-cluster-sync"></a>
547
548Newly created or updated objects can be synced throughout your
549Icinga 2 cluster. Set the `zone` attribute to the zone this object
550belongs to and let the API and cluster handle the rest.
551
552Objects without a zone attribute are only synced in the same zone the Icinga instance belongs to.
553
554> **Note**
555>
556> Cluster nodes must accept configuration for creating, modifying
557> and deleting objects. Ensure that `accept_config` is set to `true`
558> in the [ApiListener](09-object-types.md#objecttype-apilistener) object
559> on each node.
560
561If you add a new cluster instance, or reconnect an instance which has been offline
562for a while, Icinga 2 takes care of the initial object sync for all objects
563created by the API.
564
565### Querying Objects <a id="icinga2-api-config-objects-query"></a>
566
567You can request information about configuration objects by sending
568a `GET` query to the `/v1/objects/<type>` URL endpoint. `<type` has
569to be replaced with the plural name of the object type you are interested
570in:
571
572```bash
573curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/objects/hosts'
574```
575
576A list of all available configuration types is available in the
577[object types](09-object-types.md#object-types) chapter.
578
579The following URL parameters are available:
580
581  Parameters | Type         | Description
582  -----------|--------------|----------------------------
583  attrs      | Array        | **Optional.** Limited attribute list in the output.
584  joins      | Array        | **Optional.** Join related object types and their attributes specified as list (`?joins=host` for the entire set, or selectively by `?joins=host.name`).
585  meta       | Array        | **Optional.** Enable meta information using `?meta=used_by` (references from other objects) and/or `?meta=location` (location information) specified as list. Defaults to disabled.
586
587In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) may be provided.
588
589Instead of using a filter you can optionally specify the object name in the
590URL path when querying a single object. For objects with composite names
591(e.g. services) the full name (e.g. `example.localdomain!http`) must be specified:
592
593```bash
594curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/objects/services/example.localdomain!http'
595```
596
597You can limit the output to specific attributes using the `attrs` URL parameter:
598
599```bash
600curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/objects/hosts/example.localdomain?attrs=name&attrs=address&pretty=1'
601```
602
603```json
604{
605    "results": [
606        {
607            "attrs": {
608                "name": "example.localdomain",
609                "address": "192.168.1.1"
610            },
611            "joins": {},
612            "meta": {},
613            "name": "example.localdomain",
614            "type": "Host"
615        }
616    ]
617}
618```
619
620#### Object Queries Result <a id="icinga2-api-config-objects-query-result"></a>
621
622Each response entry in the results array contains the following attributes:
623
624  Attribute  | Type       | Description
625  -----------|------------|--------------
626  name       | String     | Full object name.
627  type       | String     | Object type.
628  attrs      | Dictionary | Object attributes (can be filtered using the URL parameter `attrs`).
629  joins      | Dictionary | [Joined object types](12-icinga2-api.md#icinga2-api-config-objects-query-joins) as key, attributes as nested dictionary. Disabled by default.
630  meta       | Dictionary | Contains `used_by` object references. Disabled by default, enable it using `?meta=used_by` as URL parameter.
631
632#### Object Query Joins <a id="icinga2-api-config-objects-query-joins"></a>
633
634Icinga 2 knows about object relations. For example it can optionally return
635information about the host when querying service objects.
636
637The following query retrieves all host attributes:
638
639```
640https://localhost:5665/v1/objects/services?joins=host
641```
642
643Instead of requesting all host attributes you can also limit the output to specific
644attributes:
645
646```
647https://localhost:5665/v1/objects/services?joins=host.name&joins=host.address
648```
649
650You can request that all available joins are returned in the result set by using
651the `all_joins` query parameter.
652
653```
654https://localhost:5665/v1/objects/services?all_joins=1
655```
656
657> **Note**
658>
659> For performance reasons you should only request attributes which your application
660> requires.
661
662Please note that the object type refers to the URL endpoint with `/v1/objects/<object type>`
663where the following joins are available:
664
665  Object Type  | Object Relations (`joins` prefix name)
666  -------------|------------------------------------------
667  Service      | host, check\_command, check\_period, event\_command, command\_endpoint
668  Host         | check\_command, check\_period, event\_command, command\_endpoint
669  Notification | host, service, command, period
670  Dependency   | child\_host, child\_service, parent\_host, parent\_service, period
671  User         | period
672  Zones        | parent
673
674Here's an example that retrieves all service objects for hosts which have had their `os`
675custom variable set to `Linux`. The result set contains the `display_name` and `check_command`
676attributes for the service. The query also returns the host's `name` and `address` attribute
677via a join:
678
679```bash
680curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/objects/services?attrs=display_name&attrs=check_command&joins=host.name&joins=host.address&filter=host.vars.os==%22Linux%22&pretty=1'
681```
682
683```json
684{
685    "results": [
686        {
687            "attrs": {
688                "check_command": "ping4",
689                "display_name": "ping4"
690            },
691            "joins": {
692                "host": {
693                    "address": "192.168.1.1",
694                    "name": "example.localdomain"
695                }
696            },
697            "meta": {},
698            "name": "example.localdomain!ping4",
699            "type": "Service"
700        },
701        {
702            "attrs": {
703                "check_command": "ssh",
704                "display_name": "ssh"
705            },
706            "joins": {
707                "host": {
708                    "address": "192.168.1.1",
709                    "name": "example.localdomain"
710                }
711            },
712            "meta": {},
713            "name": "example.localdomain!ssh",
714            "type": "Service"
715        }
716    ]
717}
718```
719
720> **Tip**
721>
722> Use [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override)
723> and pass everything in the request body like this:
724
725```bash
726curl -k -s -S -i -u 'root:icinga' -H 'Accept: application/json' \
727 -H 'X-HTTP-Method-Override: GET' -X POST \
728 'https://localhost:5665/v1/objects/services' \
729 -d '{ "attrs": [ "display_name", "check_command" ], "joins": [ "host.name", "host.address" ], "filter": "host.vars.os==\"Linux\"", "pretty": true }'
730```
731
732In case you want to fetch all [comments](09-object-types.md#objecttype-comment)
733for hosts and services, you can use the following query URL (similar example
734for downtimes):
735
736```
737https://localhost:5665/v1/objects/comments?joins=host&joins=service
738```
739
740This is another example for listing all service objects which are unhandled problems (state is not OK
741and no downtime or acknowledgement set). We're using [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override)
742here because we want to pass all query attributes in the request body.
743
744```bash
745curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
746 -H 'X-HTTP-Method-Override: GET' -X POST \
747 'https://127.0.0.1:5665/v1/objects/services' \
748-d '{ "joins": [ "host.name", "host.address" ], "attrs": [ "name", "state", "downtime_depth", "acknowledgement" ], "filter": "service.state != ServiceOK && service.downtime_depth == 0.0 && service.acknowledgement == 0.0", "pretty": true }'
749```
750
751```json
752{
753    "results": [
754        {
755            "attrs": {
756                "acknowledgement": 0.0,
757                "downtime_depth": 0.0,
758                "name": "10807-service",
759                "state": 3.0
760            },
761            "joins": {
762                "host": {
763                    "address": "",
764                    "name": "10807-host"
765                }
766            },
767            "meta": {},
768            "name": "10807-host!10807-service",
769            "type": "Service"
770        }
771    ]
772}
773```
774
775In order to list all acknowledgements without expire time, you query the `/v1/objects/comments`
776URL endpoint with `joins` and `filter` request parameters using the [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override)
777method:
778
779```bash
780curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
781 -H 'X-HTTP-Method-Override: GET' -X POST \
782 'https://localhost:5665/v1/objects/comments' \
783 -d '{ "joins": [ "service.name", "service.acknowledgement", "service.acknowledgement_expiry" ], "attrs": [ "author", "text" ], "filter": "service.acknowledgement!=0 && service.acknowledgement_expiry==0", "pretty": true }'
784```
785
786```json
787{
788    "results": [
789        {
790            "attrs": {
791                "author": "icingaadmin",
792                "text": "maintenance work"
793            },
794            "joins": {
795                "service": {
796                    "__name": "example.localdomain!disk /",
797                    "acknowledgement": 1.0,
798                    "acknowledgement_expiry": 0.0
799                }
800            },
801            "meta": {},
802            "name": "example.localdomain!disk /!example.localdomain-1495457222-0",
803            "type": "Comment"
804        }
805    ]
806}
807```
808
809### Creating Config Objects <a id="icinga2-api-config-objects-create"></a>
810
811New objects must be created by sending a PUT request. The following
812parameters need to be passed inside the JSON body:
813
814  Parameters        | Type         | Description
815  ------------------|--------------|--------------------------
816  templates         | Array        | **Optional.** Import existing configuration templates for this object type. Note: These templates must either be statically configured or provided in [config packages](12-icinga2-api.md#icinga2-api-config-management)-
817  attrs             | Dictionary   | **Required.** Set specific object attributes for this [object type](09-object-types.md#object-types).
818  ignore\_on\_error | Boolean      | **Optional.** Ignore object creation errors and return an HTTP 200 status instead.
819
820The object name must be specified as part of the URL path. For objects with composite names (e.g. services)
821the full name (e.g. `example.localdomain!http`) must be specified.
822
823If attributes are of the Dictionary type, you can also use the indexer format. This might be necessary to only override specific custom variables and keep all other existing custom variables (e.g. from templates):
824
825```
826"attrs": { "vars.os": "Linux" }
827```
828
829Example for creating the new host object `example.localdomain`:
830
831```bash
832curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
833 -X PUT 'https://localhost:5665/v1/objects/hosts/example.localdomain' \
834 -d '{ "templates": [ "generic-host" ], "attrs": { "address": "192.168.1.1", "check_command": "hostalive", "vars.os" : "Linux" }, "pretty": true }'
835```
836
837```json
838{
839    "results": [
840        {
841            "code": 200.0,
842            "status": "Object was created."
843        }
844    ]
845}
846```
847
848If the configuration validation fails, the new object will not be created and the response body
849contains a detailed error message. The following example is missing the `check_command` attribute
850which is required for host objects:
851
852```bash
853curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
854 -X PUT 'https://localhost:5665/v1/objects/hosts/example.localdomain' \
855 -d '{ "attrs": { "address": "192.168.1.1", "vars.os" : "Linux" }, "pretty": true }'
856```
857
858```json
859{
860    "results": [
861        {
862            "code": 500.0,
863            "errors": [
864                "Error: Validation failed for object 'example.localdomain' of type 'Host'; Attribute 'check_command': Attribute must not be empty."
865            ],
866            "status": "Object could not be created."
867        }
868    ]
869}
870```
871
872Service objects must be created using their full name ("hostname!servicename") referencing an existing host object:
873
874```bash
875curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
876 -X PUT 'https://localhost:5665/v1/objects/services/example.localdomain!realtime-load' \
877 -d '{ "templates": [ "generic-service" ], "attrs": { "check_command": "load", "check_interval": 1,"retry_interval": 1 } }'
878```
879
880Example for a new CheckCommand object:
881
882```bash
883curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
884 -X PUT 'https://localhost:5665/v1/objects/checkcommands/mytest' \
885 -d '{ "templates": [ "plugin-check-command" ], "attrs": { "command": [ "/usr/local/sbin/check_http" ], "arguments": { "-I": "$mytest_iparam$" } } }'
886```
887
888### Modifying Objects <a id="icinga2-api-config-objects-modify"></a>
889
890Existing objects must be modified by sending a `POST` request. The following
891parameters need to be passed inside the JSON body:
892
893  Parameters | Type       | Description
894  -----------|------------|---------------------------
895  attrs      | Dictionary | **Required.** Set specific object attributes for this [object type](09-object-types.md#object-types).
896
897In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters)
898parameter should be provided.
899
900> **Note**:
901>
902> Modified attributes do not trigger a re-evaluation of existing
903> static [apply rules](03-monitoring-basics.md#using-apply) and [group assignments](03-monitoring-basics.md#group-assign-intro).
904> Delete and re-create the objects if you require such changes or
905> consider funding [this feature request](https://github.com/Icinga/icinga2/issues/4084).
906>
907> Furthermore you cannot modify templates which have already been resolved
908> during [object creation](12-icinga2-api.md#icinga2-api-config-objects-create).
909> There are attributes which can only be set for [PUT requests](12-icinga2-api.md#icinga2-api-config-objects-create) such as `groups`
910> or `zone`. A complete list of `no_user_modify` attributes can be fetched from the [types](12-icinga2-api.md#icinga2-api-types) URL endpoint.
911
912If attributes are of the [Dictionary](17-language-reference.md#dictionary) type, you can also use the indexer format:
913
914```
915"attrs": { "vars.os": "Linux" }
916```
917
918The following example updates the `address` attribute and the custom variable `os` for the `example.localdomain` host:
919
920```bash
921curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
922 -X POST 'https://localhost:5665/v1/objects/hosts/example.localdomain' \
923 -d '{ "attrs": { "address": "192.168.1.2", "vars.os" : "Windows" }, "pretty": true }'
924```
925
926```json
927{
928    "results": [
929        {
930            "code": 200.0,
931            "name": "example.localdomain",
932            "status": "Attributes updated.",
933            "type": "Host"
934        }
935    ]
936}
937```
938
939### Deleting Objects <a id="icinga2-api-config-objects-delete"></a>
940
941You can delete objects created using the API by sending a `DELETE`
942request.
943
944  Parameters | Type    | Description
945  -----------|---------|---------------
946  cascade    | Boolean |  **Optional.** Delete objects depending on the deleted objects (e.g. services on a host).
947
948In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) should be provided.
949
950Example for deleting the host object `example.localdomain`:
951
952```bash
953curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
954 -X DELETE 'https://localhost:5665/v1/objects/hosts/example.localdomain?cascade=1&pretty=1'
955```
956
957```json
958{
959    "results": [
960        {
961            "code": 200.0,
962            "name": "example.localdomain",
963            "status": "Object was deleted.",
964            "type": "Host"
965        }
966    ]
967}
968```
969
970## Actions <a id="icinga2-api-actions"></a>
971
972There are several actions available for Icinga 2 provided by the `/v1/actions`
973URL endpoint. You can run actions by sending a `POST` request.
974
975The following actions are also used by [Icinga Web 2](https://icinga.com/products/icinga-web-2/):
976
977* sending check results to Icinga from scripts, remote agents, etc.
978* scheduling downtimes from external scripts or cronjobs
979* acknowledging problems
980* adding comments
981
982All actions return a 200 `OK` or an appropriate error code for each
983action performed on each object matching the supplied filter.
984
985Actions which affect the Icinga Application itself such as disabling
986notification on a program-wide basis must be applied by updating the
987[IcingaApplication object](12-icinga2-api.md#icinga2-api-config-objects)
988called `app`.
989
990```bash
991curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
992 -X POST 'https://localhost:5665/v1/objects/icingaapplications/app' \
993 -d '{ "attrs": { "enable_notifications": false } }'
994```
995
996### Unix Timestamp Handling <a id="icinga2-api-actions-unix-timestamps"></a>
997
998If you don't want to write JSON manually, especially for adding the `start_time`
999and `end_time` parameters, you can use [jo](https://github.com/jpmens/jo) to format this.
1000
1001```bash
1002jo -p pretty=true type=Service filter="service.name==\"ping4\"" author=icingaadmin comment="IPv4 network maintenance" fixed=true start_time=$(date +%s -d "+0 hour") end_time=$(date +%s -d "+1 hour")
1003```
1004
1005```json
1006{
1007   "pretty": true,
1008   "type": "Service",
1009   "filter": "service.name==\"ping4\"",
1010   "author": "icingaadmin",
1011   "comment": "IPv4 network maintenance",
1012   "fixed": true,
1013   "start_time": 1557414097,
1014   "end_time": 1557417697
1015}
1016```
1017
1018Now wrap this into the actual curl command:
1019
1020```bash
1021curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
1022 -X POST 'https://localhost:5665/v1/actions/schedule-downtime' \
1023 -d "$(jo -p pretty=true type=Service filter="service.name==\"ping4\"" author=icingaadmin comment="IPv4 network maintanence" fixed=true start_time=$(date +%s -d "+0 hour") end_time=$(date +%s -d "+1 hour"))"
1024```
1025
1026Note: This requires GNU date. On macOS, install `coreutils` from Homebrew and use `gdate`.
1027
1028### process-check-result <a id="icinga2-api-actions-process-check-result"></a>
1029
1030Process a check result for a host or a service.
1031
1032Send a `POST` request to the URL endpoint `/v1/actions/process-check-result`.
1033
1034  Parameter          | Type                           | Description
1035  ------------------ | --------------                 | --------------
1036  exit\_status       | Number                         | **Required.** For services: 0=OK, 1=WARNING, 2=CRITICAL, 3=UNKNOWN, for hosts: 0=UP, 1=DOWN.
1037  plugin\_output     | String                         | **Required.** One or more lines of the plugin main output. Does **not** contain the performance data.
1038  performance\_data  | Array<code>&#124;</code>String | **Optional.** The performance data as array of strings. The raw performance data string can be used too.
1039  check\_command     | Array<code>&#124;</code>String | **Optional.** The first entry should be the check commands path, then one entry for each command line option followed by an entry for each of its argument. Alternativly a single string can be used.
1040  check\_source      | String                         | **Optional.** Usually the name of the `command_endpoint`
1041  execution\_start   | Timestamp                      | **Optional.** The timestamp where a script/process started its execution.
1042  execution\_end     | Timestamp                      | **Optional.** The timestamp where a script/process ended its execution. This timestamp is used in features to determine e.g. the metric timestamp.
1043  ttl                | Number                         | **Optional.** Time-to-live duration in seconds for this check result. The next expected check result is `now + ttl` where freshness checks are executed.
1044
1045In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`.
1046
1047Example for the service `passive-ping`:
1048
1049```bash
1050curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
1051 -X POST 'https://localhost:5665/v1/actions/process-check-result' \
1052-d '{ "type": "Service", "filter": "host.name==\"icinga2-master1.localdomain\" && service.name==\"passive-ping\"", "exit_status": 2, "plugin_output": "PING CRITICAL - Packet loss = 100%", "performance_data": [ "rta=5000.000000ms;3000.000000;5000.000000;0.000000", "pl=100%;80;100;0" ], "check_source": "example.localdomain", "pretty": true }'
1053```
1054
1055```json
1056{
1057    "results": [
1058        {
1059            "code": 200.0,
1060            "status": "Successfully processed check result for object 'icinga2-master1.localdomain!passive-ping'."
1061        }
1062    ]
1063}
1064```
1065
1066You can avoid URL encoding of white spaces in object names by using the `filter` attribute in the request body.
1067
1068Example for using the `Host` type and filter by the host name:
1069
1070```bash
1071curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
1072 -X POST 'https://localhost:5665/v1/actions/process-check-result' \
1073 -d '{ "filter": "host.name==\"example.localdomain\"", "type": "Host", "exit_status": 1, "plugin_output": "Host is not available." }'
1074```
1075
1076
1077> **Note**
1078>
1079> Multi-line plugin output requires the following format: The first line is treated as `short` plugin output corresponding
1080> to the first line of the plugin output. Subsequent lines are treated as `long` plugin output. Please note that the
1081> performance data is separated from the plugin output and has to be passed as `performance_data` attribute.
1082
1083### reschedule-check <a id="icinga2-api-actions-reschedule-check"></a>
1084
1085Reschedule a check for hosts and services. The check can be forced if required.
1086
1087Send a `POST` request to the URL endpoint `/v1/actions/reschedule-check`.
1088
1089  Parameter    | Type      | Description
1090  -------------|-----------|--------------
1091  next\_check  | Timestamp | **Optional.** The next check will be run at this time. If omitted, the current time is used.
1092  force        | Boolean   | **Optional.** Defaults to `false`. If enabled, the checks are executed regardless of time period restrictions and checks being disabled per object or on a global basis.
1093
1094In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`.
1095
1096The example reschedules all services with the name "ping6" to immediately perform a check
1097(`next_check` default), ignoring any time periods or whether active checks are
1098allowed for the service (`force=true`).
1099
1100```bash
1101curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
1102 -X POST 'https://localhost:5665/v1/actions/reschedule-check' \
1103 -d '{ "type": "Service", "filter": "service.name==\"ping6\"", "force": true, "pretty": true }'
1104```
1105
1106```json
1107{
1108    "results": [
1109        {
1110            "code": 200.0,
1111            "status": "Successfully rescheduled check for object 'icinga2-master1.localdomain!ping6'."
1112        }
1113    ]
1114}
1115```
1116
1117### send-custom-notification <a id="icinga2-api-actions-send-custom-notification"></a>
1118
1119Send a custom notification for hosts and services. This notification
1120type can be forced being sent to all users.
1121
1122Send a `POST` request to the URL endpoint `/v1/actions/send-custom-notification`.
1123
1124  Parameter | Type    | Description
1125  ----------|---------|--------------
1126  author    | String  | **Required.** Name of the author, may be empty.
1127  comment   | String  | **Required.** Comment text, may be empty.
1128  force     | Boolean | **Optional.** Default: false. If true, the notification is sent regardless of downtimes or whether notifications are enabled or not.
1129
1130In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`.
1131
1132Example for a custom host notification announcing a global maintenance to
1133host owners:
1134
1135```bash
1136curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
1137 -X POST 'https://localhost:5665/v1/actions/send-custom-notification' \
1138 -d '{ "type": "Host", "author": "icingaadmin", "comment": "System is going down for maintenance", "force": true, "pretty": true }'
1139```
1140
1141```json
1142{
1143    "results": [
1144        {
1145            "code": 200.0,
1146            "status": "Successfully sent custom notification for object 'host0'."
1147        },
1148        {
1149            "code": 200.0,
1150            "status": "Successfully sent custom notification for object 'host1'."
1151        }
1152    ]
1153}
1154```
1155
1156### delay-notification <a id="icinga2-api-actions-delay-notification"></a>
1157
1158Delay notifications for a host or a service.
1159Note that this will only have an effect if the service stays in the same problem
1160state that it is currently in. If the service changes to another state, a new
1161notification may go out before the time you specify in the `timestamp` argument.
1162
1163Send a `POST` request to the URL endpoint `/v1/actions/delay-notification`.
1164
1165  Parameter | Type      | Description
1166  ----------|-----------|--------------
1167  timestamp | Timestamp | **Required.** Delay notifications until this timestamp.
1168
1169In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`.
1170
1171Example:
1172
1173```bash
1174curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
1175 -X POST 'https://localhost:5665/v1/actions/delay-notification' \
1176 -d '{ "type": "Service", "timestamp": 1446389894, "pretty": true }'
1177```
1178
1179```json
1180{
1181    "results": [
1182        {
1183            "code": 200.0,
1184            "status": "Successfully delayed notifications for object 'host0!service0'."
1185        },
1186        {
1187            "code": 200.0,
1188            "status": "Successfully delayed notifications for object 'host1!service1'."
1189        }
1190    ]
1191}
1192```
1193
1194### acknowledge-problem <a id="icinga2-api-actions-acknowledge-problem"></a>
1195
1196Allows you to acknowledge the current problem for hosts or services. By
1197acknowledging the current problem, future notifications (for the same state if `sticky` is set to `false`)
1198are disabled.
1199
1200Send a `POST` request to the URL endpoint `/v1/actions/acknowledge-problem`.
1201
1202  Parameter            | Type      | Description
1203  ---------------------|-----------|--------------
1204  author               | String    | **Required.** Name of the author, may be empty.
1205  comment              | String    | **Required.** Comment text, may be empty.
1206  expiry               | Timestamp | **Optional.** Whether the acknowledgement will be removed at the timestamp.
1207  sticky               | Boolean   | **Optional.** Whether the acknowledgement will be set until the service or host fully recovers. Defaults to `false`.
1208  notify               | Boolean   | **Optional.** Whether a notification of the `Acknowledgement` type will be sent. Defaults to `false`.
1209  persistent           | Boolean   | **Optional.** When the comment is of type `Acknowledgement` and this is set to `true`, the comment will remain after the acknowledgement recovers or expires. Defaults to `false`.
1210
1211In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`.
1212
1213The following example acknowledges all services which are in a hard critical state and sends out
1214a notification for them:
1215
1216```bash
1217curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
1218 -X POST 'https://localhost:5665/v1/actions/acknowledge-problem' \
1219 -d '{ "type": "Service", "filter": "service.state==2 && service.state_type==1", "author": "icingaadmin", "comment": "Global outage. Working on it.", "notify": true, "pretty": true }'
1220```
1221
1222```json
1223{
1224    "results": [
1225        {
1226            "code": 200.0,
1227            "status": "Successfully acknowledged problem for object 'icinga2-satellite1.localdomain!ping4'."
1228        },
1229        {
1230            "code": 200.0,
1231            "status": "Successfully acknowledged problem for object 'icinga2-satellite2.localdomain!ping4'."
1232        }
1233    ]
1234}
1235```
1236
1237### remove-acknowledgement <a id="icinga2-api-actions-remove-acknowledgement"></a>
1238
1239Removes the acknowledgements for services or hosts. Once the acknowledgement has
1240been removed the next notification will be sent again.
1241
1242Send a `POST` request to the URL endpoint `/v1/actions/remove-acknowledgement`.
1243
1244  Parameter | Type   | Description
1245  ----------|--------|--------------
1246  author    | String | **Optional.** Name of the removal requestor.
1247
1248In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`.
1249
1250The example removes all service acknowledgements:
1251
1252```bash
1253curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
1254 -X POST 'https://localhost:5665/v1/actions/remove-acknowledgement' \
1255 -d '{ "type": "Service", "pretty": true }'
1256```
1257
1258```json
1259{
1260    "results": [
1261        {
1262            "code": 200.0,
1263            "status": "Successfully removed acknowledgement for object 'host0!service0'."
1264        },
1265        {
1266            "code": 200.0,
1267            "status": "Successfully removed acknowledgement for object 'example2.localdomain!aws-health'."
1268        }
1269    ]
1270}
1271```
1272
1273### add-comment <a id="icinga2-api-actions-add-comment"></a>
1274
1275Adds a `comment` from an `author` to services or hosts.
1276
1277Send a `POST` request to the URL endpoint `/v1/actions/add-comment`.
1278
1279  Parameter | Type      | Description
1280  ----------|-----------|--------------
1281  author    | string    | **Required.** Name of the author, may be empty.
1282  comment   | string    | **Required.** Comment text, may be empty.
1283  expiry    | Timestamp | **Optional.** Comment expiry time.
1284
1285In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`.
1286
1287The following example adds a comment for all `ping4` services:
1288
1289```bash
1290curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
1291 -X POST 'https://localhost:5665/v1/actions/add-comment' \
1292 -d '{ "type": "Service", "filter": "service.name==\"ping4\"", "author": "icingaadmin", "comment": "Troubleticket #123456789 opened.", "pretty": true }'
1293```
1294
1295```json
1296{
1297    "results": [
1298        {
1299            "code": 200.0,
1300            "legacy_id": 26.0,
1301            "name": "icinga2-satellite1.localdomain!ping4!7e7861c8-8008-4e8d-9910-2a0bb26921bd",
1302            "status": "Successfully added comment 'icinga2-satellite1.localdomain!ping4!7e7861c8-8008-4e8d-9910-2a0bb26921bd' for object 'icinga2-satellite1.localdomain!ping4'."
1303        },
1304        {
1305            "code": 200.0,
1306            "legacy_id": 27.0,
1307            "name": "icinga2-satellite2.localdomain!ping4!9a4c43f5-9407-a536-18bf-4a6cc4b73a9f",
1308            "status": "Successfully added comment 'icinga2-satellite2.localdomain!ping4!9a4c43f5-9407-a536-18bf-4a6cc4b73a9f' for object 'icinga2-satellite2.localdomain!ping4'."
1309        }
1310    ]
1311}
1312```
1313
1314### remove-comment <a id="icinga2-api-actions-remove-comment"></a>
1315
1316Remove the comment using its `name` attribute , returns `OK` if the
1317comment did not exist.
1318**Note**: This is **not** the legacy ID but the comment name returned by
1319Icinga 2 when [adding a comment](12-icinga2-api.md#icinga2-api-actions-add-comment).
1320
1321Send a `POST` request to the URL endpoint `/v1/actions/remove-comment`.
1322
1323  Parameter | Type   | Description
1324  ----------|--------|--------------
1325  author    | String | **Optional.** Name of the removal requestor.
1326
1327In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host`, `Service` and `Comment`.
1328
1329Example for a simple filter using the `comment` URL parameter:
1330
1331```bash
1332curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
1333 -X POST 'https://localhost:5665/v1/actions/remove-comment' \
1334 -d '{ "comment": "icinga2-satellite2.localdomain!ping4!9a4c43f5-9407-a536-18bf-4a6cc4b73a9f", "pretty": true }'
1335```
1336
1337```json
1338{
1339    "results": [
1340        {
1341            "code": 200.0,
1342            "status": "Successfully removed comment 'icinga2-satellite2.localdomain!ping4!9a4c43f5-9407-a536-18bf-4a6cc4b73a9f'."
1343        }
1344    ]
1345}
1346```
1347
1348Example for removing all service comments using a service name filter for `ping4`:
1349
1350```bash
1351curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
1352 -X POST 'https://localhost:5665/v1/actions/remove-comment'
1353 -d '{ "type": "Service", "filter": "service.name==\"ping4\"", "pretty": true }'
1354```
1355
1356```json
1357{
1358    "results": [
1359        {
1360            "code": 200.0,
1361            "status": "Successfully removed all comments for object 'icinga2-satellite1.localdomain!ping4'."
1362        },
1363        {
1364            "code": 200.0,
1365            "status": "Successfully removed all comments for object 'icinga2-satellite2.localdomain!ping4'."
1366        }
1367    ]
1368}
1369```
1370
1371### schedule-downtime <a id="icinga2-api-actions-schedule-downtime"></a>
1372
1373Schedule a downtime for hosts and services.
1374
1375Send a `POST` request to the URL endpoint `/v1/actions/schedule-downtime`.
1376
1377  Parameter     | Type      | Description
1378  --------------|-----------|--------------
1379  author        | String    | **Required.** Name of the author.
1380  comment       | String    | **Required.** Comment text.
1381  start\_time   | Timestamp | **Required.** Timestamp marking the beginning of the downtime.
1382  end\_time     | Timestamp | **Required.** Timestamp marking the end of the downtime.
1383  fixed         | Boolean   | **Optional.** Defaults to `true`. If true, the downtime is `fixed` otherwise `flexible`. See [downtimes](08-advanced-topics.md#downtimes) for more information.
1384  duration      | Number    | **Required for flexible downtimes.** Duration of the downtime in seconds if `fixed` is set to false.
1385  all\_services | Boolean   | **Optional for host downtimes.** Sets downtime for [all services](12-icinga2-api.md#icinga2-api-actions-schedule-downtime-host-all-services) for the matched host objects. If `child_options` are set, all child hosts and their services will schedule a downtime too. Defaults to `false`.
1386  trigger\_name | String    | **Optional.** Sets the trigger for a triggered downtime. See [downtimes](08-advanced-topics.md#downtimes) for more information on triggered downtimes.
1387  child\_options| String    | **Optional.** Schedule child downtimes. `DowntimeNoChildren` does not do anything, `DowntimeTriggeredChildren` schedules child downtimes triggered by this downtime, `DowntimeNonTriggeredChildren` schedules non-triggered downtimes. Defaults to `DowntimeNoChildren`.
1388
1389In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`.
1390
1391Example for scheduling a downtime for all `ping4` services:
1392
1393```bash
1394curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
1395 -X POST 'https://localhost:5665/v1/actions/schedule-downtime' \
1396 -d '{ "type": "Service", "filter": "service.name==\"ping4\"", "start_time": 1446388806, "end_time": 1446389806, "duration": 1000, "author": "icingaadmin", "comment": "IPv4 network maintenance", "pretty": true }'
1397```
1398
1399```json
1400{
1401    "results": [
1402        {
1403            "code": 200.0,
1404            "legacy_id": 2.0,
1405            "name": "icinga2-satellite1.localdomain!ping4!ecc5fa55-a5b8-4189-a013-a5d4bb47af34",
1406            "status": "Successfully scheduled downtime 'icinga2-satellite1.localdomain!ping4!ecc5fa55-a5b8-4189-a013-a5d4bb47af34' for object 'icinga2-satellite1.localdomain!ping4'."
1407        },
1408        {
1409            "code": 200.0,
1410            "legacy_id": 3.0,
1411            "name": "icinga2-satellite2.localdomain!ping4!abc59032-4589-abcd-4567-ecf67856c347",
1412            "status": "Successfully scheduled downtime 'icinga2-satellite2.localdomain!ping4!abc59032-4589-abcd-4567-ecf67856c347' for object 'icinga2-satellite2.localdomain!ping4'."
1413        }
1414    ]
1415}
1416```
1417
1418In case you want to target just a single service on a host, modify the filter
1419like this:
1420
1421```
1422"filter": "host.name==\"icinga2-satellite1.localdomain\" && service.name==\"ping4\""
1423```
1424
1425#### Schedule Host Downtime(s) with all Services <a id="icinga2-api-actions-schedule-downtime-host-all-services"></a>
1426
1427Schedule a downtime for one (or multiple) hosts and all of their services.
1428Note the `all_services` attribute.
1429
1430```bash
1431curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
1432 -X POST 'https://localhost:5665/v1/actions/schedule-downtime' \
1433 -d "$(jo -p pretty=true type=Host filter="match(\"*satellite*\", host.name)" all_services=true author=icingaadmin comment="Cluster upgrade maintenance" fixed=true start_time=$(date +%s -d "+0 hour") end_time=$(date +%s -d "+1 hour"))"
1434```
1435
1436### remove-downtime <a id="icinga2-api-actions-remove-downtime"></a>
1437
1438Remove the downtime using its `name` attribute , returns `OK` if the
1439downtime did not exist.
1440**Note**: This is **not** the legacy ID but the downtime name returned by
1441Icinga 2 when [scheduling a downtime](12-icinga2-api.md#icinga2-api-actions-schedule-downtime).
1442
1443Send a `POST` request to the URL endpoint `/v1/actions/remove-downtime`.
1444
1445  Parameter | Type   | Description
1446  ----------|--------|--------------
1447  author    | String | **Optional.** Name of the removal requestor.
1448
1449In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host`, `Service` and `Downtime`.
1450
1451Example for a simple filter using the `downtime` URL parameter:
1452
1453```bash
1454curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
1455 -X POST 'https://localhost:5665/v1/actions/remove-downtime' \
1456 -d '{ "downtime": "icinga2-satellite2.localdomain!ping4!abc59032-4589-abcd-4567-ecf67856c347", "pretty": true }'
1457```
1458
1459```json
1460{
1461    "results": [
1462        {
1463            "code": 200.0,
1464            "status": "Successfully removed downtime 'icinga2-satellite2.localdomain!ping4!abc59032-4589-abcd-4567-ecf67856c347'."
1465        }
1466    ]
1467}
1468```
1469
1470Example for removing all host downtimes using a host name filter for `icinga2-satellite2.localdomain`:
1471
1472```bash
1473curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
1474 -X POST 'https://localhost:5665/v1/actions/remove-downtime' \
1475 -d '{ "type": "Host", "filter": "host.name==\"icinga2-satellite2.localdomain\"", "pretty": true }'
1476```
1477
1478```json
1479{
1480    "results": [
1481        {
1482            "code": 200.0,
1483            "status": "Successfully removed all downtimes for object 'icinga2-satellite2.localdomain'."
1484        }
1485    ]
1486}
1487```
1488
1489Example for removing a downtime from a host but not the services filtered by the author name. This example uses
1490filter variables explained in the [advanced filters](12-icinga2-api.md#icinga2-api-advanced-filters) chapter.
1491
1492```bash
1493curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
1494 -X POST 'https://localhost:5665/v1/actions/remove-downtime' \
1495 -d $'{
1496  "type": "Downtime",
1497  "filter": "host.name == filterHost && !service && downtime.author == filterAuthor",
1498  "filter_vars": {
1499    "filterHost": "icinga2-satellite1.localdomain",
1500    "filterAuthor": "icingaadmin"
1501  },
1502  "pretty": true
1503}'
1504```
1505
1506```json
1507{
1508    "results": [
1509        {
1510            "code": 200.0,
1511            "status": "Successfully removed downtime 'icinga2-satellite1.localdomain!ecc5fa55-a5b8-ef34-abcd-a5d41234af34'."
1512        }
1513    ]
1514}
1515```
1516
1517### shutdown-process <a id="icinga2-api-actions-shutdown-process"></a>
1518
1519Shuts down Icinga. May or may not return.
1520
1521Send a `POST` request to the URL endpoint `/v1/actions/shutdown-process`.
1522
1523This action does not support a target type or filter.
1524
1525Example:
1526
1527```bash
1528curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
1529 -X POST 'https://localhost:5665/v1/actions/shutdown-process?pretty=1'
1530```
1531
1532```json
1533{
1534    "results": [
1535        {
1536            "code": 200.0,
1537            "status": "Shutting down Icinga 2."
1538        }
1539    ]
1540}
1541```
1542
1543### restart-process <a id="icinga2-api-actions-restart-process"></a>
1544
1545Restarts Icinga. May or may not return.
1546
1547Send a `POST` request to the URL endpoint `/v1/actions/restart-process`.
1548
1549This action does not support a target type or filter.
1550
1551Example:
1552
1553```bash
1554curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
1555 -X POST 'https://localhost:5665/v1/actions/restart-process?pretty=1'
1556```
1557
1558```json
1559{
1560    "results": [
1561        {
1562            "code": 200.0,
1563            "status": "Restarting Icinga 2."
1564        }
1565    ]
1566}
1567```
1568
1569### generate-ticket <a id="icinga2-api-actions-generate-ticket"></a>
1570
1571Generates a PKI ticket for [CSR auto-signing](06-distributed-monitoring.md#distributed-monitoring-setup-csr-auto-signing).
1572This can be used in combination with satellite/client setups requesting this ticket number.
1573
1574> **Note**
1575>
1576> This must be used on the local host, or e.g. by a Puppet master.
1577> Doing so remotely may result in security issues with cluster
1578> trust relationships.
1579
1580Send a `POST` request to the URL endpoint `/v1/actions/generate-ticket`.
1581
1582  Parameter     | Type      | Description
1583  --------------|-----------|--------------
1584  cn            | String    | **Required.** The host's common name for which the ticket should be generated.
1585
1586Example:
1587
1588```bash
1589curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
1590 -X POST 'https://localhost:5665/v1/actions/generate-ticket' \
1591 -d '{ "cn": "icinga2-agent1.localdomain", "pretty": true }'
1592```
1593
1594```json
1595{
1596    "results": [
1597        {
1598            "code": 200.0,
1599            "status": "Generated PKI ticket '4f75d2ecd253575fe9180938ebff7cbca262f96e' for common name 'icinga2-agent1.localdomain'.",
1600            "ticket": "4f75d2ecd253575fe9180938ebff7cbca262f96e"
1601        }
1602    ]
1603}
1604```
1605
1606### execute-command <a id="icinga2-api-actions-execute-command"></a>
1607
1608Executes a particular check/notification/event-command on a particular
1609endpoint in the context of a particular checkable. Example use cases:
1610
1611* Test a check command without actually triggering notifications
1612* Reboot a node via an event command
1613* Test a notification command without actually reproducing the notification reason
1614
1615Send a `POST` request to the URL endpoint `/v1/actions/execute-command`.
1616
1617  Parameter     | Type       | Description
1618  --------------|------------|--------------
1619  ttl           | Number     | **Required.** The time to live of the execution expressed in seconds.
1620  command_type  | String     | **Optional.** The command type: `CheckCommand` or `EventCommand` or `NotificationCommand`. Default: `EventCommand`
1621  command       | String     | **Optional.** The command to execute. Its type must the same as `command_type`. It can be a macro string. Default: depending on the `command_type` it's either `$check_command$`, `$event_command$` or `$notification_command$`
1622  endpoint      | String     | **Optional.** The endpoint to execute the command on. It can be a macro string. Default: `$command_endpoint$`.
1623  macros        | Dictionary | **Optional.** Macro overrides. Default: `{}`
1624  user          | String     | **Optional.** The user used for the notification command.
1625  notification  | String     | **Optional.** The notification used for the notification command.
1626
1627Example:
1628
1629```bash
1630curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
1631 -X POST 'https://localhost:5665/v1/actions/execute-command' \
1632 -d '{"type": "Service", "service": "agent!custom_service", "ttl": 15, "macros": { "command_endpoint": "master", "ls_dir": "/tmp/foo" }, "command": "custom_command", "command_type": "CheckCommand" }'
1633```
1634
1635```json
1636{
1637    "results": [
1638        {
1639            "checkable": "agent!custom_service",
1640            "code": 202.0,
1641            "execution": "3541d906-9afe-4c0e-ae6d-f549ee9bb3e7",
1642            "status": "Accepted"
1643        }
1644    ]
1645}
1646```
1647
1648You may poll the state of the execution by [querying](#icinga2-api-config-objects-query) the checkable's attribute `executions`.
1649
1650## Event Streams <a id="icinga2-api-event-streams"></a>
1651
1652Event streams can be used to receive check results, downtimes, comments,
1653acknowledgements, etc. as a "live stream" from Icinga.
1654
1655You can for example forward these types into your own backend. Process the
1656metrics and correlate them with notifications and state changes e.g. in Elasticsearch
1657with the help of [Icingabeat](https://icinga.com/docs/icingabeat/latest/). Another use
1658case are aligned events and creating/resolving tickets automatically in your ticket system.
1659
1660You can subscribe to event streams by sending a `POST` request to the URL endpoint `/v1/events`.
1661The following parameters need to be specified (either as URL parameters or in a JSON-encoded message body):
1662
1663  Parameter  | Type         | Description
1664  -----------|--------------|-------------
1665  types      | Array        | **Required.** Event type(s). Multiple types as URL parameters are supported.
1666  queue      | String       | **Required.** Unique queue name. Multiple HTTP clients can use the same queue as long as they use the same event types and filter.
1667  filter     | String       | **Optional.** Filter for specific event attributes using [filter expressions](12-icinga2-api.md#icinga2-api-filters).
1668
1669### Event Stream Types <a id="icinga2-api-event-streams-types"></a>
1670
1671The following event stream types are available:
1672
1673  Type                   | Description
1674  -----------------------|--------------
1675  CheckResult            | Check results for hosts and services.
1676  StateChange            | Host/service state changes.
1677  Notification           | Notification events including notified users for hosts and services.
1678  AcknowledgementSet     | Acknowledgement set on hosts and services.
1679  AcknowledgementCleared | Acknowledgement cleared on hosts and services.
1680  CommentAdded           | Comment added for hosts and services.
1681  CommentRemoved         | Comment removed for hosts and services.
1682  DowntimeAdded          | Downtime added for hosts and services.
1683  DowntimeRemoved        | Downtime removed for hosts and services.
1684  DowntimeStarted        | Downtime started for hosts and services.
1685  DowntimeTriggered      | Downtime triggered for hosts and services.
1686  ObjectCreated          | Object created for all Icinga 2 objects.
1687  ObjectDeleted          | Object deleted for all Icinga 2 objects.
1688  ObjectModified         | Object modified for all Icinga 2 objects.
1689
1690Note: Each type requires [API permissions](12-icinga2-api.md#icinga2-api-permissions)
1691being set.
1692
1693Example for all downtime events:
1694
1695```
1696&types=DowntimeAdded&types=DowntimeRemoved&types=DowntimeTriggered
1697
1698-d '{ "types": ["DowntimeAdded", "DowntimeRemoved", "DowntimeTriggered"] }'
1699```
1700
1701Example for all object events:
1702
1703```
1704&types=ObjectCreated&types=ObjectDeleted&types=ObjectModified
1705
1706-d '{ "types": ["ObjectCreated", "ObjectDeleted", "ObjectModified"] }'
1707```
1708
1709#### <a id="icinga2-api-event-streams-type-checkresult"></a> Event Stream Type: CheckResult
1710
1711  Name             | Type          | Description
1712  -----------------|---------------|--------------------------
1713  type             | String        | Event type `CheckResult`.
1714  timestamp        | Timestamp     | Unix timestamp when the event happened.
1715  host             | String        | [Host](09-object-types.md#objecttype-host) name.
1716  service          | String        | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host check result.
1717  check\_result    | CheckResult   | Serialized [CheckResult](08-advanced-topics.md#advanced-value-types-checkresult) value type.
1718  downtime\_depth  | Number        | Amount of active downtimes on the checkable.
1719  acknowledgement  | Boolean       | Whether the object is acknowledged.
1720
1721#### <a id="icinga2-api-event-streams-type-statechange"></a> Event Stream Type: StateChange
1722
1723  Name             | Type          | Description
1724  -----------------|---------------|--------------------------
1725  type             | String        | Event type `StateChange`.
1726  timestamp        | Timestamp     | Unix timestamp when the event happened.
1727  host             | String        | [Host](09-object-types.md#objecttype-host) name.
1728  service          | String        | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host state change.
1729  state            | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state.
1730  state\_type      | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state type.
1731  check\_result    | CheckResult   | Serialized [CheckResult](08-advanced-topics.md#advanced-value-types-checkresult) value type.
1732  downtime\_depth  | Number        | Amount of active downtimes on the checkable.
1733  acknowledgement  | Boolean       | Whether the object is acknowledged.
1734
1735#### <a id="icinga2-api-event-streams-type-notification"></a> Event Stream Type: Notification
1736
1737  Name 		| Type          | Description
1738  --------------|---------------|--------------------------
1739  type 	        | String        | Event type `Notification`.
1740  timestamp     | Timestamp     | Unix timestamp when the event happened.
1741  host	        | String        | [Host](09-object-types.md#objecttype-host) name.
1742  service       | String        | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host notification.
1743  command       | String        | [NotificationCommand](09-object-types.md#objecttype-notificationcommand) name.
1744  users         | Array         | List of notified [user](09-object-types.md#objecttype-user) names.
1745  notification\_type | String   | [$notification.type$](03-monitoring-basics.md#notification-runtime-macros) runtime macro value.
1746  author        | String        | [$notification.author$](03-monitoring-basics.md#notification-runtime-macros) runtime macro value.
1747  text          | String        | [$notification.comment$](03-monitoring-basics.md#notification-runtime-macros) runtime macro value.
1748  check\_result	| CheckResult   | Serialized [CheckResult](08-advanced-topics.md#advanced-value-types-checkresult) value type.
1749
1750#### <a id="icinga2-api-event-streams-type-flapping"></a> Event Stream Type: Flapping
1751
1752  Name              | Type          | Description
1753  ------------------|---------------|--------------------------
1754  type              | String        | Event type `Flapping`.
1755  timestamp         | Timestamp     | Unix timestamp when the event happened.
1756  host              | String        | [Host](09-object-types.md#objecttype-host) name.
1757  service           | String        | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host flapping event.
1758  state             | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state.
1759  state\_type       | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state type.
1760  is\_flapping      | Boolean       | Whether this object is flapping.
1761  current\_flapping | Number        | Current flapping value in percent (added in 2.8).
1762  threshold\_low    | Number        | Low threshold in percent (added in 2.8).
1763  threshold\_high   | Number        | High threshold in percent (added in 2.8).
1764
1765#### <a id="icinga2-api-event-streams-type-acknowledgementset"></a> Event Stream Type: AcknowledgementSet
1766
1767  Name 		| Type          | Description
1768  --------------|---------------|--------------------------
1769  type 	        | String        | Event type `AcknowledgementSet`.
1770  timestamp     | Timestamp     | Unix timestamp when the event happened.
1771  host	        | String        | [Host](09-object-types.md#objecttype-host) name.
1772  service       | String        | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host acknowledgement.
1773  state	        | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state.
1774  state\_type   | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state type.
1775  author        | String        | Acknowledgement author set via [acknowledge-problem](12-icinga2-api.md#icinga2-api-actions-acknowledge-problem) action.
1776  comment       | String        | Acknowledgement comment set via [acknowledge-problem](12-icinga2-api.md#icinga2-api-actions-acknowledge-problem) action.
1777  acknowledgement\_type | Number | 0 = None, 1 = Normal, 2 = Sticky. `sticky` can be set via [acknowledge-problem](12-icinga2-api.md#icinga2-api-actions-acknowledge-problem) action.
1778  notify        | Boolean       | Notifications were enabled via [acknowledge-problem](12-icinga2-api.md#icinga2-api-actions-acknowledge-problem) action.
1779  expiry        | Timestamp     | Acknowledgement expire time set via [acknowledge-problem](12-icinga2-api.md#icinga2-api-actions-acknowledge-problem) action.
1780
1781#### <a id="icinga2-api-event-streams-type-acknowledgementcleared"></a> Event Stream Type: AcknowledgementCleared
1782
1783  Name 		| Type          | Description
1784  --------------|---------------|--------------------------
1785  type 	        | String        | Event type `AcknowledgementCleared`.
1786  timestamp     | Timestamp     | Unix timestamp when the event happened.
1787  host	        | String        | [Host](09-object-types.md#objecttype-host) name.
1788  service       | String        | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host acknowledgement.
1789  state	        | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state.
1790  state\_type   | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state type.
1791
1792#### <a id="icinga2-api-event-streams-type-commentadded"></a> Event Stream Type: CommentAdded
1793
1794  Name 		| Type          | Description
1795  --------------|---------------|--------------------------
1796  type 	        | String        | Event type `CommentAdded`.
1797  timestamp     | Timestamp     | Unix timestamp when the event happened.
1798  comment       | Dictionary    | Serialized [Comment](09-object-types.md#objecttype-comment) object.
1799
1800#### <a id="icinga2-api-event-streams-type-commentremoved"></a> Event Stream Type: CommentRemoved
1801
1802  Name 		| Type          | Description
1803  --------------|---------------|--------------------------
1804  type 	        | String        | Event type `CommentRemoved`.
1805  timestamp     | Timestamp     | Unix timestamp when the event happened.
1806  comment       | Dictionary    | Serialized [Comment](09-object-types.md#objecttype-comment) object.
1807
1808#### <a id="icinga2-api-event-streams-type-downtimeadded"></a> Event Stream Type: DowntimeAdded
1809
1810  Name 		| Type          | Description
1811  --------------|---------------|--------------------------
1812  type 	        | String        | Event type `DowntimeAdded`.
1813  timestamp     | Timestamp     | Unix timestamp when the event happened.
1814  downtime      | Dictionary    | Serialized [Comment](09-object-types.md#objecttype-downtime) object.
1815
1816#### <a id="icinga2-api-event-streams-type-downtimeremoved"></a> Event Stream Type: DowntimeRemoved
1817
1818  Name 		| Type          | Description
1819  --------------|---------------|--------------------------
1820  type 	        | String        | Event type `DowntimeRemoved`.
1821  timestamp     | Timestamp     | Unix timestamp when the event happened.
1822  downtime      | Dictionary    | Serialized [Comment](09-object-types.md#objecttype-downtime) object.
1823
1824
1825#### <a id="icinga2-api-event-streams-type-downtimestarted"></a> Event Stream Type: DowntimeStarted
1826
1827  Name 		| Type          | Description
1828  --------------|---------------|--------------------------
1829  type 	        | String        | Event type `DowntimeStarted`.
1830  timestamp     | Timestamp     | Unix timestamp when the event happened.
1831  downtime      | Dictionary    | Serialized [Comment](09-object-types.md#objecttype-downtime) object.
1832
1833
1834#### <a id="icinga2-api-event-streams-type-downtimetriggered"></a> Event Stream Type: DowntimeTriggered
1835
1836  Name 		| Type          | Description
1837  --------------|---------------|--------------------------
1838  type 	        | String        | Event type `DowntimeTriggered`.
1839  timestamp     | Timestamp     | Unix timestamp when the event happened.
1840  downtime      | Dictionary    | Serialized [Comment](09-object-types.md#objecttype-downtime) object.
1841
1842
1843### Event Stream Filter <a id="icinga2-api-event-streams-filter"></a>
1844
1845Event streams can be filtered by attributes using the prefix `event.`.
1846
1847Example for the `CheckResult` type with the `exit_code` set to `2`:
1848
1849```
1850&types=CheckResult&filter=event.check_result.exit_status==2
1851
1852-d '{ "types": [ "CheckResult" ], "filter": "event.check_result.exit_status==2" }'
1853```
1854
1855Example for the `CheckResult` type with the service [matching](18-library-reference.md#global-functions-match)
1856the string pattern "random\*":
1857
1858```
1859&types=CheckResult&filter=match%28%22random*%22,event.service%29
1860
1861-d { "types": [ "CheckResult" ], "filter": "match(\"random*\", event.service)" }
1862```
1863
1864### Event Stream Response <a id="icinga2-api-event-streams-response"></a>
1865
1866The event stream response is separated with new lines. The HTTP client
1867must support long-polling and HTTP/1.1. HTTP/1.0 is not supported.
1868
1869Example:
1870
1871```bash
1872curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
1873 -X POST 'https://localhost:5665/v1/events' \
1874 -d '{ "queue": "myqueue", "types": [ "CheckResult" ], "filter": "event.check_result.exit_status==2" }'
1875```
1876
1877```
1878{"check_result":{ ... },"host":"example.localdomain","service":"ping4","timestamp":1445421319.7226390839,"type":"CheckResult"}
1879{"check_result":{ ... },"host":"example.localdomain","service":"ping4","timestamp":1445421324.7226390839,"type":"CheckResult"}
1880{"check_result":{ ... },"host":"example.localdomain","service":"ping4","timestamp":1445421329.7226390839,"type":"CheckResult"}
1881```
1882
1883## Status and Statistics <a id="icinga2-api-status"></a>
1884
1885Send a `GET` request to the URL endpoint `/v1/status` to retrieve status information and statistics for Icinga 2.
1886
1887Example:
1888
1889```bash
1890curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/status?pretty=1'
1891```
1892
1893```
1894{
1895    "results": [
1896        {
1897            "name": "ApiListener",
1898            "perfdata": [ ... ],
1899            "status": [ ... ]
1900        },
1901        ...
1902        {
1903            "name": "IcingaAplication",
1904            "perfdata": [ ... ],
1905            "status": [ ... ]
1906        },
1907        ...
1908    ]
1909}
1910```
1911
1912You can limit the output by specifying a status type in the URL, e.g. `IcingaApplication`:
1913
1914```bash
1915curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/status/IcingaApplication?pretty=1'
1916```
1917
1918```json
1919{
1920    "results": [
1921        {
1922            "perfdata": [],
1923            "status": {
1924                "icingaapplication": {
1925                    "app": {
1926                        "enable_event_handlers": true,
1927                        "enable_flapping": true,
1928                        "enable_host_checks": true,
1929                        "enable_notifications": true,
1930                        "enable_perfdata": true,
1931                        "enable_service_checks": true,
1932                        "node_name": "example.localdomain",
1933                        "pid": 59819.0,
1934                        "program_start": 1443019345.093372,
1935                        "version": "v2.3.0-573-g380a131"
1936                    }
1937                }
1938            }
1939        }
1940    ]
1941}
1942```
1943
1944## Configuration Management <a id="icinga2-api-config-management"></a>
1945
1946The main idea behind configuration management is that external applications
1947can create configuration packages and stages based on configuration files and
1948directory trees. This replaces any additional SSH connection and whatnot to
1949dump configuration files to Icinga 2 directly.
1950
1951In case you are pushing a new configuration stage to a package, Icinga 2 will
1952validate the configuration asynchronously and populate a status log which
1953can be fetched in a separated request. Once the validation succeeds,
1954a reload is triggered by default.
1955
1956This functionality was primarly developed for the [Icinga Director](https://icinga.com/docs/director/latest/)
1957but can be used with your own deployments too. It also solves the problem
1958with certain runtime objects (zones, endpoints) and can be used to
1959deploy global templates in [global cluster zones](06-distributed-monitoring.md#distributed-monitoring-global-zone-config-sync).
1960
1961
1962### Create a Config Package <a id="icinga2-api-config-management-create-package"></a>
1963
1964Send a `POST` request to a new config package called `example-cmdb` in this example. This
1965creates a new empty configuration package.
1966
1967```bash
1968curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
1969-X POST 'https://localhost:5665/v1/config/packages/example-cmdb?pretty=1'
1970```
1971
1972```json
1973{
1974    "results": [
1975        {
1976            "code": 200.0,
1977            "package": "example-cmdb",
1978            "status": "Created package."
1979        }
1980    ]
1981}
1982```
1983
1984Package names with the `_` prefix are reserved for internal packages and must not be used.
1985You can recognize `_api`, `_etc` and `_cluster` when querying specific objects and packages.
1986
1987Each configuration object stores the package source in the `package` attribute.
1988
1989### Create a Stage: Upload Configuration <a id="icinga2-api-config-management-create-config-stage"></a>
1990
1991Configuration files in packages are managed in stages. Stages provide a way
1992to maintain multiple configuration versions for a package. Once a new stage
1993is deployed, the content is validated and set as active stage on success.
1994
1995On failure, the older stage remains active, and the caller can fetch the `startup.log`
1996from this stage deployment attempt to see what exactly failed. You can see that
1997in the Director's deployment log.
1998
1999Send a `POST` request to the URL endpoint `/v1/config/stages` and add the name of an existing
2000configuration package to the URL path (e.g. `example-cmdb`).
2001The request body must contain the `files` attribute with the value being
2002a dictionary of file targets and their content.
2003
2004Optional attributes include `reload` (defaults to `true`) and `activate` (defaults to `true`).
2005The `reload` attribute will tell icinga2 to reload after stage config validation.
2006The `activate` attribute will tell icinga2 to activate the stage if it validates.
2007If `activate` is set to `false`, `reload` must also be `false`.
2008
2009The file path requires one of these two directories inside its path:
2010
2011  Directory   | Description
2012  ------------|------------------------------------
2013  conf.d      | Local configuration directory.
2014  zones.d     | Configuration directory for cluster zones, each zone must be put into its own zone directory underneath. Supports the [cluster config sync](06-distributed-monitoring.md#distributed-monitoring-top-down-config-sync).
2015
2016Example for a local configuration in the `conf.d` directory:
2017
2018```
2019"files": { "conf.d/host1.conf": "object Host \"local-host\" { address = \"127.0.0.1\", check_command = \"hostalive\" }" }
2020```
2021
2022Example for a host configuration inside the `satellite` zone in the `zones.d` directory:
2023
2024```
2025"files": { "zones.d/satellite/host2.conf": "object Host \"satellite-host\" { address = \"192.168.1.100\", check_command = \"hostalive\" }" }
2026```
2027
2028
2029The example below will create a new file called `test.conf` in the `conf.d`
2030directory. Note: This example contains an error (`chec_command`). This is
2031intentional.
2032
2033```bash
2034curl -k -s -S -i -u root:icinga -H 'Accept: application/json' -X POST \
2035-d '{ "files": { "conf.d/test.conf": "object Host \"cmdb-host\" { chec_command = \"dummy\" }" }, "pretty": true }' \
2036'https://localhost:5665/v1/config/stages/example-cmdb'
2037```
2038
2039```json
2040{
2041    "results": [
2042        {
2043            "code": 200.0,
2044            "package": "example-cmdb",
2045            "stage": "7e7861c8-8008-4e8d-9910-2a0bb26921bd",
2046            "status": "Created stage. Reload triggered."
2047        }
2048    ]
2049}
2050```
2051
2052The Icinga 2 API returns the `package` name this stage was created for, and also
2053generates a unique name for the `stage` attribute you'll need for later requests.
2054
2055Icinga 2 automatically restarts the daemon in order to activate the new config stage. This
2056can be disabled by setting `reload` to `false` in the request.
2057If the validation for the new config stage failed, the old stage
2058and its configuration objects will remain active.
2059
2060Activation may be inhibited even for stages that validate correctly by setting
2061`activate` to `false`. This may be useful for validating the contents of a stage
2062without making it active, for example in a CI (continuous integration) system.
2063
2064> **Note**
2065>
2066> Old stages are not purged automatically. You can [remove stages](12-icinga2-api.md#icinga2-api-config-management-delete-config-stage) that are no longer in use.
2067
2068Icinga 2 creates the following files in the configuration package
2069stage after configuration validation:
2070
2071  File        | Description
2072  ------------|--------------
2073  status      | Contains the [configuration validation](11-cli-commands.md#config-validation) exit code (everything else than 0 indicates an error).
2074  startup.log | Contains the [configuration validation](11-cli-commands.md#config-validation) output.
2075
2076You can [fetch these files](12-icinga2-api.md#icinga2-api-config-management-fetch-config-package-stage-files)
2077in order to verify that the new configuration was deployed successfully. Please follow the chapter below
2078to learn more about this.
2079
2080
2081### List Configuration Packages and their Stages <a id="icinga2-api-config-management-list-config-packages"></a>
2082
2083A list of packages and their stages can be retrieved by sending a `GET` request to the URL endpoint `/v1/config/packages`.
2084
2085The following example contains one configuration package `example-cmdb`. The package does not currently
2086have an active stage.
2087
2088```bash
2089curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/config/packages?pretty=1'
2090```
2091
2092```json
2093{
2094    "results": [
2095        {
2096            "active-stage": "",
2097            "name": "example-cmdb",
2098            "stages": [
2099                "7e7861c8-8008-4e8d-9910-2a0bb26921bd"
2100            ]
2101        }
2102    ]
2103}
2104```
2105
2106### List Configuration Package Stage Files <a id="icinga2-api-config-management-list-config-package-stage-files"></a>
2107
2108In order to retrieve a list of files for a stage you can send a `GET` request to
2109the URL endpoint `/v1/config/stages`. You need to include
2110the package name (`example-cmdb`) and stage name (`7e7861c8-8008-4e8d-9910-2a0bb26921bd`) in the URL:
2111
2112```bash
2113curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/config/stages/example-cmdb/7e7861c8-8008-4e8d-9910-2a0bb26921bd?pretty=1'
2114```
2115
2116```
2117{
2118    "results": [
2119...
2120        {
2121            "name": "startup.log",
2122            "type": "file"
2123        },
2124        {
2125            "name": "status",
2126            "type": "file"
2127        },
2128        {
2129            "name": "conf.d",
2130            "type": "directory"
2131        },
2132        {
2133            "name": "zones.d",
2134            "type": "directory"
2135        },
2136        {
2137            "name": "conf.d/test.conf",
2138            "type": "file"
2139        }
2140    ]
2141}
2142```
2143
2144### Fetch Configuration Package Stage Files <a id="icinga2-api-config-management-fetch-config-package-stage-files"></a>
2145
2146Send a `GET` request to the URL endpoint `/v1/config/files` and add
2147the package name, the stage name and the relative path to the file to the URL path.
2148
2149> **Note**
2150>
2151> The returned files are plain-text instead of JSON-encoded.
2152
2153The following example fetches the configuration file `conf.d/test.conf`:
2154
2155```bash
2156curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/config/files/example-cmdb/7e7861c8-8008-4e8d-9910-2a0bb26921bd/conf.d/test.conf'
2157```
2158
2159```
2160object Host "cmdb-host" { chec_command = "dummy" }
2161```
2162
2163You can fetch a [list of existing files](12-icinga2-api.md#icinga2-api-config-management-list-config-package-stage-files)
2164in a configuration stage and then specifically request their content.
2165
2166### Configuration Package Stage Errors <a id="icinga2-api-config-management-config-package-stage-errors"></a>
2167
2168Now that we don't have an active stage for `example-cmdb` yet seen [here](12-icinga2-api.md#icinga2-api-config-management-list-config-packages),
2169there must have been an error.
2170
2171In order to check for validation errors you can fetch the `startup.log` file
2172by sending a `GET` request to the URL endpoint `/v1/config/files`. You must include
2173the package name, stage name and the `startup.log` in the URL path.
2174
2175```bash
2176curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/config/files/example-cmdb/7e7861c8-8008-4e8d-9910-2a0bb26921bd/startup.log'
2177```
2178
2179```
2180[...]
2181critical/config: Error: Attribute 'chec_command' does not exist.
2182Location:
2183/var/lib/icinga2/api/packages/example-cmdb/7e7861c8-8008-4e8d-9910-2a0bb26921bd/conf.d/test.conf(1): object Host "cmdb-host" { chec_command = "dummy" }
2184                                                                                                       ^^^^^^^^^^^^^^^^^^^^^^
2185
2186critical/config: 1 error
2187```
2188
2189The output is the exact as known from [configuration validation](11-cli-commands.md#config-validation).
2190
2191> **Note**
2192>
2193> The returned output is plain-text instead of JSON-encoded.
2194
2195
2196### Deleting Configuration Package Stage <a id="icinga2-api-config-management-delete-config-stage"></a>
2197
2198You can send a `DELETE` request to the URL endpoint `/v1/config/stages`
2199in order to purge a configuration stage. You must include the package and
2200stage name inside the URL path.
2201
2202The following example removes the failed configuration stage `7e7861c8-8008-4e8d-9910-2a0bb26921bd`
2203in the `example-cmdb` configuration package:
2204
2205```bash
2206curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
2207 -X DELETE 'https://localhost:5665/v1/config/stages/example-cmdb/7e7861c8-8008-4e8d-9910-2a0bb26921bd?pretty=1'
2208```
2209
2210```json
2211{
2212    "results": [
2213        {
2214            "code": 200.0,
2215            "status": "Stage deleted."
2216        }
2217    ]
2218}
2219```
2220
2221### Deleting Configuration Package <a id="icinga2-api-config-management-delete-config-package"></a>
2222
2223In order to completely purge a configuration package and its stages
2224you can send a `DELETE` request to the URL endpoint `/v1/config/packages`
2225with the package name in the URL path.
2226
2227This example entirely deletes the configuration package `example-cmdb`:
2228
2229```bash
2230curl -k -s -S -i -u root:icinga -H 'Accept: application/json' -X DELETE \
2231'https://localhost:5665/v1/config/packages/example-cmdb?pretty=1'
2232```
2233
2234```json
2235{
2236    "results": [
2237        {
2238            "code": 200.0,
2239            "package": "example-cmdb",
2240            "status": "Deleted package."
2241        }
2242    ]
2243}
2244```
2245
2246## Types <a id="icinga2-api-types"></a>
2247
2248You can retrieve the configuration object types by sending a `GET` request to URL
2249endpoint `/v1/types`.
2250
2251Each response entry in the results array contains the following attributes:
2252
2253  Attribute       | Type         | Description
2254  ----------------|--------------|---------------------
2255  name            | String       | The type name.
2256  plural\_name    | String       | The plural type name.
2257  fields          | Dictionary   | Available fields including details on e.g. the type and attribute accessibility.
2258  abstract        | Boolean      | Whether objects can be instantiated for this type.
2259  base            | Boolean      | The base type (e.g. `Service` inherits fields and prototype methods from `Checkable`).
2260  prototype\_keys | Array        | Available prototype methods.
2261
2262In order to view a specific configuration object type specify its name inside the URL path:
2263
2264```bash
2265curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/types/Object?pretty=1'
2266```
2267
2268```json
2269{
2270    "results": [
2271        {
2272            "abstract": false,
2273            "fields": {
2274                "type": {
2275                    "array_rank": 0.0,
2276                    "attributes": {
2277                        "config": false,
2278                        "navigation": false,
2279                        "no_user_modify": false,
2280                        "no_user_view": false,
2281                        "required": false,
2282                        "state": false
2283                    },
2284                    "id": 0.0,
2285                    "type": "String"
2286                }
2287            },
2288            "name": "Object",
2289            "plural_name": "Objects",
2290            "prototype_keys": [
2291                "clone",
2292                "notify_attribute",
2293                "to_string"
2294            ]
2295        }
2296    ]
2297}
2298```
2299
2300## Config Templates <a id="icinga2-api-config-templates"></a>
2301
2302Provides methods to manage configuration templates:
2303
2304* [querying templates](12-icinga2-api.md#icinga2-api-config-templates-query)
2305
2306Creation, modification and deletion of templates at runtime is not supported.
2307
2308### Querying Templates <a id="icinga2-api-config-templates-query"></a>
2309
2310You can request information about configuration templates by sending
2311a `GET` query to the `/v1/templates/<type>` URL endpoint. `<type` has
2312to be replaced with the plural name of the object type you are interested
2313in:
2314
2315```bash
2316curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/templates/hosts'
2317```
2318
2319A list of all available configuration types is available in the
2320[object types](09-object-types.md#object-types) chapter.
2321
2322A [filter](12-icinga2-api.md#icinga2-api-filters) may be provided for this query type. The
2323template object can be accessed in the filter using the `tmpl` variable. In this
2324example the [match function](18-library-reference.md#global-functions-match) is used to
2325check a wildcard string pattern against `tmpl.name`.
2326The `filter` attribute is passed inside the request body thus requiring to use [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override)
2327here.
2328
2329```bash
2330curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
2331 -H 'X-HTTP-Method-Override: GET' -X POST \
2332 'https://localhost:5661/v1/templates/hosts' \
2333 -d '{ "filter": "match(\"g*\", tmpl.name)" }'
2334```
2335
2336Instead of using a filter you can optionally specify the template name in the
2337URL path when querying a single object:
2338
2339```bash
2340curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/templates/hosts/generic-host'
2341```
2342
2343The result set contains the type, name as well as the location of the template.
2344
2345## Variables <a id="icinga2-api-variables"></a>
2346
2347Provides methods to manage global variables:
2348
2349* [querying variables](12-icinga2-api.md#icinga2-api-variables-query)
2350
2351### Querying Variables <a id="icinga2-api-variables-query"></a>
2352
2353You can request information about global variables by sending
2354a `GET` query to the `/v1/variables/` URL endpoint:
2355
2356```bash
2357curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/variables'
2358```
2359
2360A [filter](12-icinga2-api.md#icinga2-api-filters) may be provided for this query type. The
2361variable information object can be accessed in the filter using the `variable` variable.
2362The `filter` attribute is passed inside the request body thus requiring to use [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override)
2363here.
2364
2365```bash
2366curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
2367 -H 'X-HTTP-Method-Override: GET' -X POST \
2368 'https://localhost:5661/v1/variables' \
2369 -d '{ "filter": "variable.type in [ \"String\", \"Number\" ]" }'
2370```
2371
2372Instead of using a filter you can optionally specify the variable name in the
2373URL path when querying a single variable:
2374
2375```bash
2376curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/variables/PrefixDir'
2377```
2378
2379The result set contains the type, name and value of the global variable.
2380
2381## Debug Console <a id="icinga2-api-console"></a>
2382
2383You can inspect variables and execute other expressions by sending a `POST` request to the URL endpoint `/v1/console/execute-script`.
2384In order to receive auto-completion suggestions, send a `POST` request to the URL endpoint `/v1/console/auto-complete-script`.
2385
2386> **Note**
2387>
2388> This functionality is used by the [debug console](11-cli-commands.md#cli-command-console). Do not use this in production, unless
2389> you are aware of the fact that expressions and commands may crash the daemon, or lead into
2390> unwanted behaviour. Use this URL endpoint **read-only** when needed.
2391
2392The following parameters need to be specified (either as URL parameters or in a JSON-encoded message body):
2393
2394  Parameter  | Type         | Description
2395  -----------|--------------|-------------
2396  session    | String       | **Optional.** The session ID. Ideally this should be a GUID or some other unique identifier.
2397  command    | String       | **Required.** Command expression for execution or auto-completion.
2398  sandboxed  | Number       | **Optional.** Whether runtime changes are allowed or forbidden. Defaults to disabled.
2399
2400The [API permission](12-icinga2-api.md#icinga2-api-permissions) `console` is required for executing
2401expressions.
2402
2403> **Note**
2404>
2405> Runtime modifications via `execute-script` calls are not validated and might cause the Icinga 2
2406> daemon to crash or behave in an unexpected way. Use these runtime changes at your own risk.
2407
2408If you specify a session identifier, the same script context can be reused for multiple requests. This allows you to, for example, set a local variable in a request and use that local variable in another request. Sessions automatically expire after a set period of inactivity (currently 30 minutes).
2409
2410Example for fetching the command line from the local host's last check result:
2411
2412```bash
2413curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
2414 -X POST 'https://localhost:5665/v1/console/execute-script?command=get_host(NodeName).last_check_result.command&sandboxed=0&session=bb75fd7c-c686-407d-9688-582c04227756&pretty=1'
2415```
2416
2417```json
2418{
2419    "results": [
2420        {
2421            "code": 200.0,
2422            "result": [
2423                "/usr/local/sbin/check_ping",
2424                "-H",
2425                "127.0.0.1",
2426                "-c",
2427                "5000,100%",
2428                "-w",
2429                "3000,80%"
2430            ],
2431            "status": "Executed successfully."
2432        }
2433    ]
2434}
2435```
2436
2437Example for fetching auto-completion suggestions for the `Host.` type. This works in a
2438similar fashion when pressing TAB inside the [console CLI command](11-cli-commands.md#cli-command-console):
2439
2440```bash
2441curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \
2442 -X POST 'https://localhost:5665/v1/console/auto-complete-script?command=Host.&sandboxed=0&session=bb75fd7c-c686-407d-9688-582c04227756&pretty=1'
2443```
2444
2445```json
2446{
2447    "results": [
2448        {
2449            "code": 200.0,
2450            "status": "Auto-completed successfully.",
2451            "suggestions": [
2452                "Host.type",
2453                "Host.name",
2454                "Host.prototype",
2455                "Host.base",
2456                "Host.register_attribute_handler",
2457                "Host.clone",
2458                "Host.notify_attribute",
2459                "Host.to_string"
2460            ]
2461        }
2462    ]
2463}
2464```
2465
2466## API Clients <a id="icinga2-api-clients"></a>
2467
2468After its initial release in 2015, community members
2469and developers have been working hard to add more REST API
2470clients and integrations into DevOps tools.
2471
2472* [Libraries](12-icinga2-api.md#icinga2-api-clients-libraries)
2473* [Status](12-icinga2-api.md#icinga2-api-clients-status)
2474* [Management](12-icinga2-api.md#icinga2-api-clients-management)
2475* [Event Streams](12-icinga2-api.md#icinga2-api-clients-event-streams)
2476* [Actions](12-icinga2-api.md#icinga2-api-clients-actions)
2477* [REST API Apps](12-icinga2-api.md#icinga2-api-clients-apps)
2478
2479Additional [programmatic examples](12-icinga2-api.md#icinga2-api-clients-programmatic-examples)
2480will help you getting started using the Icinga 2 API in your environment.
2481
2482### Libraries <a id="icinga2-api-clients-libraries"></a>
2483
2484Name												| Language	| Description
2485------------------------------------------------------------------------------------------------|---------------|--------------------------------------------------------
2486[ruby-icinga2](https://github.com/bodsch/ruby-icinga2)                                          | Ruby          | Ruby library
2487[python-icinga2_api](https://github.com/KevinHonka/Icinga2_Python_API)                          | Python        | Python library
2488[python-icinga2-api](https://github.com/fmnisme/python-icinga2api)				| Python	| Python bindings for Icinga 2 interaction
2489[python-icinga2-api-continued](https://github.com/joni1993/icinga2apic)                         | Python        | Python bindings for Icinga 2 interaction forked and continued from fmnisme's python binding
2490[go-icinga2](https://github.com/xert/go-icinga2)						| Golang	| Golang functions and type definitions
2491[go-icinga2-api](https://github.com/lrsmith/go-icinga2-api/)					| Golang	| Golang implementation used inside the Terraform provider
2492[go-icinga2-client](https://github.com/Nexinto/go-icinga2-client)     | Golang  | Golang implementation for the Rancher integration.
2493[Monitoring::Icinga2::Client::REST](https://metacpan.org/release/THESEAL/Monitoring-Icinga2-Client-REST-2.0.0) | Perl | Perl bindings.
2494[Icinga 2 API in PHP](https://github.com/uniwue-rz/icinga2-api)					| PHP		| PHP implementation. For other examples, look into Icinga Web 2 and Director.
2495
2496### Status <a id="icinga2-api-clients-status"></a>
2497
2498Name												| Language	| Description
2499------------------------------------------------------------------------------------------------|---------------|--------------------------------------------------------
2500[Dashing](https://github.com/dnsmichi/dashing-icinga2)						| Ruby, HTML	| Dashboard for Dashing querying the REST API for current host/service/global status
2501[InfluxDB Telegraf Input](https://github.com/influxdata/telegraf/blob/master/plugins/inputs/icinga2/README.md) | Golang	| [Telegraf](https://github.com/influxdata/telegraf) is an agent written in Go for collecting, processing, aggregating, and writing metrics.
2502[Icinga Slack Bot](https://github.com/bb-Ricardo/icinga-slack-bot)				| Python	| It can be used to interact with Icinga2 from your Slack client. It uses the Icinga2 API to get Host/Service status details. Simple status filters can be used to narrow down the returned status list.
2503[Icinga 2 Slack Bot](https://github.com/mlabouardy/icinga2-slack-bot) 				| Golang | Query host/service details from a [Slack](https://slack.com/) channel
2504[icinga2bot](https://github.com/reikoNeko/icinga2bot)						| Python	| [Errbot](https://errbot.io/en/latest/user_guide/setup.html) plugin to fetch status and event stream information and forward to XMPP, IRC, etc.
2505[IcingaBusyLightAgent](https://github.com/stdevel/IcingaBusylightAgent) 			| C#		| Notification Agent in Systray
2506[BitBar for OSX](https://getbitbar.com/plugins/Dev/Icinga2/icinga2.24m.py)			| Python	| macOS tray app for highlighting the host/service status
2507[Icinga 2 Multistatus](https://chrome.google.com/webstore/detail/icinga-multi-status/khabbhcojgkibdeipanmiphceeoiijal/related)	| - 	| Chrome Extension
2508[Naglite4](https://github.com/wftech/icinga2-naglite4)						| Python	| Naglite3 rewrite using the Icinga 2 REST API.
2509[icinga-telegram-bot](https://github.com/joni1993/icinga-telegram-bot)				| Python	| Telegram Bot using the Icinga 2 REST API
2510
2511### Manage Objects <a id="icinga2-api-clients-management"></a>
2512
2513Name												| Language	| Description
2514------------------------------------------------------------------------------------------------|---------------|--------------------------------------------------------
2515[Icinga Director](https://icinga.com/docs/director/latest) 					| PHP, JS	| Icinga 2 configuration interface with a nice frontend, and automated imports for nearly any source.
2516[Terraform Provider](https://github.com/terraform-providers/terraform-provider-icinga2)		| Golang	| Register hosts from Terraform in Icinga 2. [Official docs](https://www.terraform.io/docs/providers/icinga2/index.html).
2517[Kube Icinga](https://github.com/gyselroth/kube-icinga)			                        | Typescript    | Monitor Kubernetes services / resources using icinga2 (including autodiscovery support)
2518[Logstash output for Icinga](https://www.icinga.com/products/integrations/elastic/)             | Ruby          | Forward check results and create objects from log events
2519[Foreman Smart Proxy Monitoring](https://github.com/theforeman/smart_proxy_monitoring)		| Ruby		| Smart Proxy extension for Foreman creating and deleting hosts and services in Icinga 2
2520[Rancher integration](https://github.com/Nexinto/rancher-icinga)         		        | Golang        | Registers [Rancher](https://rancher.com) resources in Icinga 2 for monitoring.
2521[AWS/EC2](https://github.com/Icinga/icinga2-api-examples/tree/master/aws-ec2)			| Ruby		| Example script for creating and deleting AWS instances in Icinga 2
2522[Ansible Host Module](https://docs.ansible.com/ansible/latest/modules/icinga2_host_module.html) | Python 	| In progress, [Ansible Feature](https://docs.ansible.com/ansible/latest/modules/icinga2_feature_module.html#icinga2-feature-module) is also there.
2523[gocinga](https://gitlab.com/sambadevi/gocinga)							| Golang	| CLI Tool for Icinga, written in go
2524
2525### Event Streams <a id="icinga2-api-clients-event-streams"></a>
2526
2527Name												| Language	| Description
2528------------------------------------------------------------------------------------------------|---------------|--------------------------------------------------------
2529[Elastic Icingabeat](https://icinga.com/docs/icingabeat/latest/)				| Golang	| Process events and send to Elasticsearch/Logstash outputs
2530[Request Tracker ticket integration](https://github.com/bytemine/icinga2rt)			| Golang	| Create and update RT tickets
2531[Logstash input event stream](https://github.com/bobapple/logstash-input-icinga_eventstream)	| Ruby		| Forward events as Logstash input
2532[Flapjack events](https://github.com/sol1/flapjack-icinga2)					| Golang	| Dumping events into Redis for Flapjack processing
2533[Stackstorm integration](https://github.com/StackStorm-Exchange/stackstorm-icinga2)		| Python	| Processing events and fetching status information
2534[NodeJS consumer](https://community.icinga.com/t/consume-api-event-stream/1010/6)		| NodeJS	| Example from our community :)
2535
2536### Actions <a id="icinga2-api-clients-actions"></a>
2537
2538Name												| Language	| Description
2539------------------------------------------------------------------------------------------------|---------------|--------------------------------------------------------
2540[Icinga Web 2](https://icinga.com/docs/icingaweb2/latest/)                                      | PHP           | Trigger actions via command transport
2541[Logstash output for Icinga](https://www.icinga.com/products/integrations/elastic/)             | Ruby          | Forward check results and create objects from log events
2542[OTRS SystemMonitoring](https://github.com/OTRS/SystemMonitoring)                               | Perl          | Acknowledge problems in Icinga 2 from OTRS tickets
2543[mqttwarn](https://github.com/jpmens/mqttwarn#icinga2)						| Python	| Forward check results from mqttwarn to Icinga 2
2544[Lita handler](https://github.com/tuxmea/lita-icinga2)						| Ruby		| List, recheck and acknowledge through a #chatops bot called [Lita](https://github.com/litaio/lita)
2545[Sakuli forwarder](http://sakuli.readthedocs.io/en/latest/forwarder-icinga2api/)		| Java		| Forward check results from tests from [Sakuli](https://github.com/ConSol/sakuli) to Icinga 2
2546[OpsGenie actions](https://www.opsgenie.com/docs/integrations/icinga2-integration)		| Golang, Java	| Integrate Icinga 2 into OpsGenie
2547
2548
2549### REST API Apps <a id="icinga2-api-clients-apps"></a>
2550
2551Name												| Language	| Description
2552------------------------------------------------------------------------------------------------|---------------|--------------------------------------------------------
2553Browser plugins											| -		| [Postman for Chrome](https://www.getpostman.com), [RESTED for Firefox](https://addons.mozilla.org/en-US/firefox/addon/rested/)
2554[Postman](https://www.getpostman.com/)                                                          | -             | App instead of browser plugin
2555[Cocoa Rest Client](https://mmattozzi.github.io/cocoa-rest-client/)                              | -             | macOS app
2556[Paw for MacOS](https://paw.cloud)								| (exported)	| Paw is a full-featured HTTP client that lets you test and describe the APIs you build or consume. It has a beautiful native macOS interface to compose requests, inspect server responses, generate client code and export API definitions.
2557
2558
2559### Programmatic Examples <a id="icinga2-api-clients-programmatic-examples"></a>
2560
2561The following languages are covered:
2562
2563* [Python](12-icinga2-api.md#icinga2-api-clients-programmatic-examples-python)
2564* [Ruby](12-icinga2-api.md#icinga2-api-clients-programmatic-examples-ruby)
2565* [PHP](12-icinga2-api.md#icinga2-api-clients-programmatic-examples-php)
2566* [Perl](12-icinga2-api.md#icinga2-api-clients-programmatic-examples-perl)
2567* [Golang](12-icinga2-api.md#icinga2-api-clients-programmatic-examples-golang)
2568* [Powershell](12-icinga2-api.md#icinga2-api-clients-programmatic-examples-powershell)
2569
2570The [request method](icinga2-api-requests) is `POST` using [X-HTTP-Method-Override: GET](12-icinga2-api.md#icinga2-api-requests-method-override)
2571which allows you to send a JSON request body. The examples request specific service
2572attributes joined with host attributes. `attrs` and `joins` are therefore specified
2573as array.
2574The `filter` attribute [matches](18-library-reference.md#global-functions-match)
2575on all services with `ping` in their name.
2576
2577#### Example API Client in Python <a id="icinga2-api-clients-programmatic-examples-python"></a>
2578
2579The following example uses **Python** and the `requests` and `json` module:
2580
2581```
2582# pip install requests
2583# pip install json
2584
2585$ vim icinga.py
2586
2587#!/usr/bin/env python
2588
2589import requests, json
2590
2591# Replace 'localhost' with your FQDN and certificate CN
2592# for TLS verification
2593request_url = "https://localhost:5665/v1/objects/services"
2594headers = {
2595        'Accept': 'application/json',
2596        'X-HTTP-Method-Override': 'GET'
2597        }
2598data = {
2599        "attrs": [ "name", "state", "last_check_result" ],
2600        "joins": [ "host.name", "host.state", "host.last_check_result" ],
2601        "filter": "match(\"ping*\", service.name)",
2602}
2603
2604r = requests.post(request_url,
2605        headers=headers,
2606        auth=('root', 'icinga'),
2607        data=json.dumps(data),
2608        verify="pki/icinga2-ca.crt")
2609
2610print "Request URL: " + str(r.url)
2611print "Status code: " + str(r.status_code)
2612
2613if (r.status_code == 200):
2614        print "Result: " + json.dumps(r.json())
2615else:
2616        print r.text
2617        r.raise_for_status()
2618
2619$ python icinga.py
2620```
2621
2622#### Example API Client in Ruby <a id="icinga2-api-clients-programmatic-examples-ruby"></a>
2623
2624The following example uses **Ruby** and the `rest_client` gem:
2625
2626```
2627# gem install rest_client
2628
2629$ vim icinga.rb
2630
2631#!/usr/bin/ruby
2632
2633require 'rest_client'
2634
2635# Replace 'localhost' with your FQDN and certificate CN
2636# for TLS verification
2637request_url = "https://localhost:5665/v1/objects/services"
2638headers = {
2639        "Accept" => "application/json",
2640        "X-HTTP-Method-Override" => "GET"
2641}
2642data = {
2643        "attrs" => [ "name", "state", "last_check_result" ],
2644        "joins" => [ "host.name", "host.state", "host.last_check_result" ],
2645        "filter" => "match(\"ping*\", service.name)",
2646}
2647
2648r = RestClient::Resource.new(
2649        URI.encode(request_url),
2650        :headers => headers,
2651        :user => "root",
2652        :password => "icinga",
2653        :ssl_ca_file => "pki/icinga2-ca.crt")
2654
2655begin
2656        response = r.post(data.to_json)
2657rescue => e
2658        response = e.response
2659end
2660
2661puts "Status: " + response.code.to_s
2662if response.code == 200
2663        puts "Result: " + (JSON.pretty_generate JSON.parse(response.body))
2664else
2665        puts "Error: " + response
2666end
2667
2668$ ruby icinga.rb
2669```
2670
2671A more detailed example can be found in the [Dashing demo](https://github.com/Icinga/dashing-icinga2).
2672
2673#### Example API Client in PHP <a id="icinga2-api-clients-programmatic-examples-php"></a>
2674
2675The following example uses **PHP** and its `curl` library:
2676
2677```
2678$ vim icinga.php
2679
2680#!/usr/bin/env php
2681<?php
2682# Replace 'localhost' with your FQDN and certificate CN
2683# for TLS verification
2684$request_url = "https://localhost:5665/v1/objects/services";
2685$username = "root";
2686$password = "icinga";
2687$headers = array(
2688        'Accept: application/json',
2689        'X-HTTP-Method-Override: GET'
2690);
2691$data = array(
2692        attrs => array('name', 'state', 'last_check_result'),
2693        joins => array('host.name', 'host.state', 'host.last_check_result'),
2694        filter => 'match("ping*", service.name)',
2695);
2696
2697$ch = curl_init();
2698curl_setopt_array($ch, array(
2699        CURLOPT_URL => $request_url,
2700        CURLOPT_HTTPHEADER => $headers,
2701        CURLOPT_USERPWD => $username . ":" . $password,
2702        CURLOPT_RETURNTRANSFER => true,
2703        CURLOPT_CAINFO => "pki/icinga2-ca.crt",
2704        CURLOPT_POST => count($data),
2705        CURLOPT_POSTFIELDS => json_encode($data)
2706));
2707
2708$response = curl_exec($ch);
2709if ($response === false) {
2710        print "Error: " . curl_error($ch) . "(" . $response . ")\n";
2711}
2712
2713$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
2714curl_close($ch);
2715print "Status: " . $code . "\n";
2716
2717if ($code == 200) {
2718        $response = json_decode($response, true);
2719        print_r($response);
2720}
2721?>
2722
2723$ php icinga.php
2724```
2725
2726#### Example API Client in Perl <a id="icinga2-api-clients-programmatic-examples-perl"></a>
2727
2728The following example uses **Perl** and the `Rest::Client` module:
2729
2730```
2731# perl -MCPAN -e 'install REST::Client'
2732# perl -MCPAN -e 'install JSON'
2733# perl -MCPAN -e 'install MIME::Base64'
2734# perl -MCPAN -e 'install Data::Dumper'
2735
2736$ vim icinga.pl
2737
2738#!/usr/bin/env perl
2739
2740use strict;
2741use warnings;
2742use REST::Client;
2743use MIME::Base64;
2744use JSON;
2745use Data::Dumper;
2746
2747# Replace 'localhost' with your FQDN and certificate CN
2748# for TLS verification
2749my $request_host = "https://localhost:5665";
2750my $userpass = "root:icinga";
2751
2752my $client = REST::Client->new();
2753$client->setHost($request_host);
2754$client->setCa("pki/icinga2-ca.crt");
2755$client->addHeader("Accept", "application/json");
2756$client->addHeader("X-HTTP-Method-Override", "GET");
2757$client->addHeader("Authorization", "Basic " . encode_base64($userpass));
2758my %json_data = (
2759        attrs => ['name', 'state', 'last_check_result'],
2760        joins => ['host.name', 'host.state', 'host.last_check_result'],
2761        filter => 'match("ping*", service.name)',
2762);
2763my $data = encode_json(\%json_data);
2764$client->POST("/v1/objects/services", $data);
2765
2766my $status = $client->responseCode();
2767print "Status: " . $status . "\n";
2768my $response = $client->responseContent();
2769if ($status == 200) {
2770        print "Result: " . Dumper(decode_json($response)) . "\n";
2771} else {
2772        print "Error: " . $response . "\n";
2773}
2774
2775$ perl icinga.pl
2776```
2777
2778
2779#### Example API Client in Golang <a id="icinga2-api-clients-programmatic-examples-golang"></a>
2780
2781Requires the Golang build chain.
2782
2783```
2784$ vim icinga.go
2785
2786package main
2787
2788import (
2789	"bytes"
2790	"crypto/tls"
2791	"log"
2792	"io/ioutil"
2793	"net/http"
2794)
2795
2796func main() {
2797	var urlBase= "https://localhost:5665"
2798	var apiUser= "root"
2799	var apiPass= "icinga"
2800
2801	urlEndpoint := urlBase + "/v1/objects/services"
2802
2803	tr := &http.Transport{
2804		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
2805	}
2806	httpClient := &http.Client{Transport: tr}
2807
2808	var requestBody = []byte(`{
2809		"attrs": [ "name", "state", "last_check_result" ],
2810		"joins": [ "host.name", "host.state", "host.last_check_result" ],
2811		"filter": "match(\"ping*\", service.name)"
2812	}`)
2813
2814	req, err := http.NewRequest("POST", urlEndpoint, bytes.NewBuffer(requestBody))
2815	req.Header.Set("Accept", "application/json")
2816	req.Header.Set("X-HTTP-Method-Override", "GET")
2817
2818	req.SetBasicAuth(apiUser, apiPass)
2819
2820	resp, err := httpClient.Do(req)
2821	if err != nil {
2822		log.Fatal("Server error:", err)
2823		return
2824	}
2825	defer resp.Body.Close()
2826
2827	log.Print("Response status:", resp.Status)
2828
2829	bodyBytes, _ := ioutil.ReadAll(resp.Body)
2830	bodyString := string(bodyBytes)
2831
2832	if resp.StatusCode == http.StatusOK {
2833		log.Print("Result: " + bodyString)
2834	} else {
2835		log.Fatal(bodyString)
2836	}
2837}
2838```
2839
2840Build the binary:
2841
2842```bash
2843go build icinga.go
2844./icinga
2845```
2846
2847#### Example API Client in Powershell <a id="icinga2-api-clients-programmatic-examples-powershell"></a>
2848
2849This example compares the given certificate with the certificate from icinga2 for a trusted connection.
2850More info: https://stackoverflow.com/a/58494718/9397788
2851
2852Invoke-RestMethod with PUT is buggy with Powershell 3.0. So we need at least Powershell 4.0.
2853https://stackoverflow.com/questions/18278977/powershell-v3-invoke-restmethod-headers
2854
2855
2856```
2857$icingaApiHost     = "icinga.master.local"
2858$IcingaApiPort     = 5665
2859$icingaApiUser     = "root"
2860$icingaApiPassword = "icinga"
2861
2862$requestUrl = "https://{0}:{1}/v1/objects/services" -f $icingaApiHost,$IcingaApiPort
2863
2864
2865# Put the certificate from your master (/etc/icinga2/pki/*.crt) here.
2866# You will get it with "openssl s_client -connect <master>:5665" too.
2867
2868$cert64=@"
2869	-----BEGIN CERTIFICATE-----
2870	MIIE5TCCAs2gAwIBAgIBAjANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAlJY2lu
2871	Z2EgQ0EwHhcNMTYwNzA3MDYxOTM4WhcNMzEwNzA0MDYxOTM4WjAiMSAwHgYDVQQD
2872	DBdpY2luZ2EuZXh0ZXJuMS56bXQuaW5mbzCCAiIwDQYJKoZIhvcNAQEBBQADggIP
2873	ADCCAgoCggIBAJ2/ufxCb1m8PbUCxLkZqZNLxZ/vpulOcKmOGYm6VBWbOXQA50on
2874	IewnMRUDGF9DHajLk1nyUu1TyKxGzBbja+06/kVd/8Muv0MUNF6iC1U3F3h0W9da
2875	kk5rK1L+A534csHCFcG3dZkbdOMrh5hy4kMf9c2FEpviL54Fo4e+b3ZJFA6rv5D9
2876	7LzaxfLcsMwXIZ/WRnxjjfnA+RenHeYLlNM8Uk3vqI6tBc1qpFzFeRWMbclFzSLN
2877	5x+J6cuyFjVi+Vv8c6SU6W3ykw8Vvq1QQUixl9lwxqNJNsWWfGR8ycmFiv1ZYxiu
2878	HpmuLslExZ2qxdGe/raMBEOGgVsUTDZNyTm/9TxgOa3m9cv3R0YIFUmfoBQ3d51S
2879	wburJG2eC0ETpnt0TptwMdTfL+HYVWB71djg2Pb8R3vldnhFVpy9vyx3FyHoN7ZQ
2880	h7+r6HK2jpwWo7/jK9ExpglVoV8vUbNYqXiA/lZGEkT3YLwTyUhqXKei3Xu2CGGR
2881	UId6fAj6OWk9TLW+OaR9BcS74mpiTWNDlbEP+/LQnUhte8scX5cSqBzy4vpuG1G+
2882	NGDbYcG4xn6Pc6qt/QddKU/pB/GbJv9SlHU8SjSt09oG9GtuXVjPoZX5msi3NmMy
2883	DpAcab5Lx4MgOS/GwRLRI3IjZ3ZK+UkLvRgesSH5/JPUIgfTdr/Eg5dVAgMBAAGj
2884	NDAyMAwGA1UdEwEB/wQCMAAwIgYDVR0RBBswGYIXaWNpbmdhLmV4dGVybjEuem10
2885	LmluZm8wDQYJKoZIhvcNAQELBQADggIBAEpEJt35KZuvDzU/xrVaVC3ct6CHmXOh
2886	DDj5PdwkYtO0vw9WE7aVc88Fs6uhW2BxFkLvm7TpJ6g05egtBozHYrhTEir/fPna
2887	rVAD9wEQU6KuSayeToXlgWhKDRAAv1lrQwU4xAAdJP8faxQGc7nAwN/h0g14UTmU
2888	LSkyJU4a+1SkEUOs2YCq9vChS3MowO+6I35e98dIA1swHLeQ/QJowspODQvi6pGX
2889	VH8FaaqfGwhv+gMwDoAW9hB74VZXO8I3mueZUccPiJXlaojx5hpaHRNRvpdBPclA
2890	HHLRQniEOkai2Wg2cft/wq6/fYLE/yv5ej15MNyt3Wjj41DEK5B/bvmN/chOrZlv
2891	8rh3ek12ngVtXF+Jcmfsij8+hj/IOM6SeELtW+c0KRaPoVR7oR9o6ce/dyfiw6Hv
2892	iQsAV6x//kytpRnUY3VAH4QTJzQ5bgz1Cwr6H+cWE2ca4MHCtPYaZnDiOv4b/Yz7
2893	97Nrc7QPGewMl0hYeykpLP2hBJldw01NXhztuq1j38vYY38lKCN6v1INUujEUZg7
2894	NwgfHUvJmGIE/fwLAvP7do8gf+1MGPEimsgvias5YtDtrEOz7K/oF3Qgk3sepwAz
2895	XXlNLnJAY4p0d/sgCCFQnstQMM95X0Y6cfITzkz3HIUcNF2sbvVnn8xHi0TSH/8J
2896	tPLHO1xOLz7N
2897	-----END CERTIFICATE-----
2898"@
2899
2900# register callback for comparing the certificate
2901function set-SSLCertificate {
2902    param(
2903        $Cert
2904    )
2905
2906    if (-not("validateCert" -as [type])) {
2907        add-type -TypeDefinition @"
2908            using System.Net.Security;
2909            using System.Security.Cryptography.X509Certificates;
2910
2911            public static class ValidateCert {
2912                static X509Certificate2 MyCert;
2913
2914                public static bool Validate(object sender,
2915                    X509Certificate cert,
2916                    X509Chain chain,
2917                    SslPolicyErrors sslPolicyErrors) {
2918                        if (MyCert.Equals(cert)) {
2919                            return true;
2920                        } else {
2921                            return false;
2922                        }
2923                }
2924
2925                public static RemoteCertificateValidationCallback GetDelegate(X509Certificate2 Cert) {
2926                    MyCert = Cert;
2927                    return new RemoteCertificateValidationCallback(ValidateCert.Validate);
2928                }
2929            }
2930"@
2931    }
2932    [System.Net.ServicePointManager]::ServerCertificateValidationCallback = [validateCert]::GetDelegate($Cert)
2933}
2934
2935# convert base64 based certificate to X509 certificate
2936function get-x509 {
2937    param(
2938        [string]
2939            $Cert64
2940    )
2941
2942    $CertBin=[System.Convert]::FromBase64String(($Cert64.Trim(" ") -replace "-.*-",""))
2943
2944    Write-Host ($Cert64.Trim(" ") -replace "-.*-","")
2945
2946    [System.Security.Cryptography.X509Certificates.X509Certificate2]$CertBin
2947}
2948
2949# Allow TLS 1.2. Old powershell (.net) uses TLS 1.0 only. Icinga2 >2.10 needs TLS 1.2
2950[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
2951
2952$SecPass = ConvertTo-SecureString $icingaApiPassword -AsPlainText -Force
2953$Cred = New-Object System.Management.Automation.PSCredential($icingaApiUser, $SecPass)
2954
2955$Cert = get-x509 $Cert64
2956set-SSLCertificate $Cert
2957
2958$httpHeaders = @{
2959    "X-HTTP-Method-Override" = "GET"
2960    "accept"                 = "application/json"
2961}
2962
2963$attrs =  @( "name", "state", "last_check_result" )
2964$joins = @( "host.name", "host.state", "host.last_check_result")
2965$filter = 'match("ping*", service.name)'
2966
2967$data = @{
2968    "attrs" = $attrs
2969    "joins" = $joins
2970    "filter" = $filter
2971}
2972
2973$result = Invoke-RestMethod -Uri $requestUrl -Method "POST" -Body (ConvertTo-Json -InputObject $data)  -Credential $Cred -ContentType "application/json" -Headers $httpHeaders
2974
2975foreach ($s in $result.results) {
2976    Write-Host "Service " $s.attrs.name " on Host " $s.joins.host.name "State " $s.attrs.state " Output: " $s.attrs.last_check_result.output
2977    # Debug
2978    Write-Host "Debug: Attributes " $s.attrs | ConvertTo-Json
2979    Write-Host "Debug: Joins Host" $s.joins.host | ConvertTo-Json
2980    Write-Host "`n"
2981}
2982```
2983
2984Run the Powershell ISE as administrator, and execute the script as you change it.
2985
2986![Icinga 2 API Windows Powershell ISE Script](images/api/icinga2_api_powershell_ise.png)
2987
2988
2989Alternatively, save the code and run it in Powershell:
2990
2991```
2992.\icinga.ps1
2993```
2994