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