]> granicus.if.org Git - icinga2/blob - doc/12-icinga2-api.md
e88ca62267420087f7ec408a45c0f23861a46dc2
[icinga2] / doc / 12-icinga2-api.md
1 # Icinga 2 API <a id="icinga2-api"></a>
2
3 ## Setting up the API <a id="icinga2-api-setup"></a>
4
5 You can run the CLI command `icinga2 api setup` to enable the
6 `api` [feature](11-cli-commands.md#enable-features) and set up
7 certificates as well as a new API user `root` with an auto-generated password in the
8 `/etc/icinga2/conf.d/api-users.conf` configuration file:
9
10     # icinga2 api setup
11
12 Make sure to restart Icinga 2 to enable the changes you just made:
13
14     # service icinga2 restart
15
16 If you prefer to set up the API manually, you will have to perform the following steps:
17
18 * Set up X.509 certificates for Icinga 2
19 * Enable the `api` feature (`icinga2 feature enable api`)
20 * Create an `ApiUser` object for authentication
21
22 The next chapter provides a quick overview of how you can use the API.
23
24 ### Creating ApiUsers <a id="icinga2-api-creating-users"></a>
25
26 The CLI command `icinga2 api user` allows you to create an ApiUser object with a hashed password string, ready to be
27 added to your configuration. Example:
28
29 ```
30 $ icinga2 api user --user icingaweb2 --password icinga
31 object ApiUser "icingaweb2" {
32   password_hash ="$5$d5f1a17ea308acb6$9e9fd5d24a9373a16e8811765cc5a5939687faf9ef8ed496db6e7f1d0ae9b2a9"
33   // client_cn = ""
34
35   permissions = [ "*" ]
36 }
37 ```
38
39 Optionally a salt can be provided with `--salt`, otherwise a random value will be used. When ApiUsers are stored this
40 way, even somebody able to read the configuration files won't be able to authenticate using this information. There is
41 no way to recover your password should you forget it, you'd need to create it anew.
42
43 ## Introduction <a id="icinga2-api-introduction"></a>
44
45 The Icinga 2 API allows you to manage configuration objects
46 and resources in a simple, programmatic way using HTTP requests.
47
48 The URL endpoints are logically separated allowing you to easily
49 make calls to
50
51 * query, create, modify and delete [config objects](12-icinga2-api.md#icinga2-api-config-objects)
52 * perform [actions](12-icinga2-api.md#icinga2-api-actions) (reschedule checks, etc.)
53 * subscribe to [event streams](12-icinga2-api.md#icinga2-api-event-streams)
54 * [manage configuration packages](12-icinga2-api.md#icinga2-api-config-management)
55 * evaluate [script expressions](12-icinga2-api.md#icinga2-api-console)
56
57 ### Requests <a id="icinga2-api-requests"></a>
58
59 Any tool capable of making HTTP requests can communicate with
60 the API, for example [curl](https://curl.haxx.se/).
61
62 Requests are only allowed to use the HTTPS protocol so that
63 traffic remains encrypted.
64
65 By default the Icinga 2 API listens on port `5665` which is shared with
66 the cluster stack. The port can be changed by setting the `bind_port` attribute
67 for the [ApiListener](09-object-types.md#objecttype-apilistener)
68 object in the `/etc/icinga2/features-available/api.conf`
69 configuration file.
70
71 Supported request methods:
72
73   Method | Usage
74   -------|--------
75   GET    | Retrieve information about configuration objects. Any request using the GET method is read-only and does not affect any objects.
76   POST   | Update attributes of a specified configuration object.
77   PUT    | Create a new object. The PUT request must include all attributes required to create a new object.
78   DELETE | Remove an object created by the API. The DELETE method is idempotent and does not require any check if the object actually exists.
79
80 All requests apart from `GET` require that the following `Accept` header is set:
81
82     Accept: application/json
83
84 Each URL is prefixed with the API version (currently "/v1").
85
86 ### Responses <a id="icinga2-api-responses"></a>
87
88 Successful requests will send back a response body containing a `results`
89 list. Depending on the number of affected objects in your request, the
90 `results` list may contain more than one entry.
91
92 The output will be sent back as a JSON object:
93
94
95     {
96         "results": [
97             {
98                 "code": 200.0,
99                 "status": "Object was created."
100             }
101         ]
102     }
103
104 > **Tip**
105 >
106 > You can use the `pretty` parameter to beautify the JSON response with Icinga v2.9+.
107
108 You can also use [jq](https://stedolan.github.io/jq/) or `python -m json.tool`
109 in combination with curl on the CLI.
110
111 ```
112 curl ... | python -m json.tool
113 ```
114
115 > **Note**
116 >
117 > Future versions of Icinga 2 might set additional fields. Your application
118 > should gracefully handle fields it is not familiar with, for example by
119 > ignoring them.
120
121 ### HTTP Statuses <a id="icinga2-api-http-statuses"></a>
122
123 The API will return standard [HTTP statuses](https://www.ietf.org/rfc/rfc2616.txt)
124 including error codes.
125
126 When an error occurs, the response body will contain additional information
127 about the problem and its source.
128
129 A status code between 200 and 299 generally means that the request was
130 successful.
131
132 Return codes within the 400 range indicate that there was a problem with the
133 request. Either you did not authenticate correctly, you are missing the authorization
134 for your requested action, the requested object does not exist or the request
135 was malformed.
136
137 A status in the range of 500 generally means that there was a server-side problem
138 and Icinga 2 is unable to process your request.
139
140 ### Authentication <a id="icinga2-api-authentication"></a>
141
142 There are two different ways for authenticating against the Icinga 2 API:
143
144 * username and password using HTTP basic auth
145 * X.509 certificate
146
147 In order to configure a new API user you'll need to add a new [ApiUser](09-object-types.md#objecttype-apiuser)
148 configuration object. In this example `root` will be the basic auth username
149 and the `password` attribute contains the basic auth password.
150
151     # vim /etc/icinga2/conf.d/api-users.conf
152
153     object ApiUser "root" {
154       password = "icinga"
155     }
156
157 Alternatively you can use X.509 client certificates by specifying the `client_cn`
158 the API should trust. The X.509 certificate has to be signed by the CA certificate
159 that is configured in the [ApiListener](09-object-types.md#objecttype-apilistener) object.
160
161     # vim /etc/icinga2/conf.d/api-users.conf
162
163     object ApiUser "root" {
164       client_cn = "CertificateCommonName"
165     }
166
167 An `ApiUser` object can have both authentication methods configured.
168
169 You can test authentication by sending a GET request to the API:
170
171     $ curl -k -s -u root:icinga 'https://localhost:5665/v1'
172
173 In case you get an error message make sure to check the API user credentials.
174
175 When using client certificates for authentication you'll need to pass your client certificate
176 and private key to the curl call:
177
178     $ curl -k --cert example.localdomain.crt --key example.localdomain.key 'https://example.localdomain:5665/v1/status'
179
180 In case of an error make sure to verify the client certificate and CA.
181
182 The curl parameter `-k` disables certificate verification and should therefore
183 only be used for testing. In order to securely check each connection you'll need to
184 specify the trusted CA certificate using the curl parameter`--cacert`:
185
186     $ curl -u root:icinga --cacert ca.crt 'icinga2.node1.localdomain:5665/v1'
187
188 Read the next chapter on [API permissions](12-icinga2-api.md#icinga2-api-permissions)
189 in order to configure authorization settings for your newly created API user.
190
191 ### Permissions <a id="icinga2-api-permissions"></a>
192
193 By default an API user does not have any permissions to perform
194 actions on the URL endpoints.
195
196 Permissions for API users must be specified in the `permissions` attribute
197 as array. The array items can be a list of permission strings with wildcard
198 matches.
199
200 Example for an API user with all permissions:
201
202     permissions = [ "*" ]
203
204 Note that you can use wildcards. Here's another example that only allows the user
205 to perform read-only object queries for hosts and services:
206
207     permissions = [ "objects/query/Host", "objects/query/Service" ]
208
209 You can also further restrict permissions by specifying a filter expression. The
210 filter expression has to be a [lambda function](17-language-reference.md#nullary-lambdas)
211 which must return a boolean value.
212
213 The following example allows the API user to query all hosts and services which have a
214 custom attribute `os` that matches the regular expression `^Linux`.
215 The [regex function](18-library-reference.md#global-functions-regex) is available as global function.
216
217     permissions = [
218       {
219         permission = "objects/query/Host"
220         filter = {{ regex("^Linux", host.vars.os) }}
221       },
222       {
223         permission = "objects/query/Service"
224         filter = {{ regex("^Linux", service.vars.os) }}
225       }
226     ]
227
228 More information about filters can be found in the [filters](12-icinga2-api.md#icinga2-api-filters) chapter.
229
230 Permissions are tied to a maximum HTTP request size to prevent abuse, responses sent by Icinga are not limited.
231 An API user with all permissions ("\*") may send up to 512 MB regardless of the endpoint.
232
233 Available permissions for specific URL endpoints:
234
235   Permissions                   | URL Endpoint  | Supports filters  | Max body size in MB
236   ------------------------------|---------------|-------------------|---------------------
237   actions/&lt;action&gt;        | /v1/actions   | Yes               | 1
238   config/query                  | /v1/config    | No                | 1
239   config/modify                 | /v1/config    | No                | 512
240   console                       | /v1/console   | No                | 1
241   events/&lt;type&gt;           | /v1/events    | No                | 1
242   objects/query/&lt;type&gt;    | /v1/objects   | Yes               | 1
243   objects/create/&lt;type&gt;   | /v1/objects   | No                | 1
244   objects/modify/&lt;type&gt;   | /v1/objects   | Yes               | 1
245   objects/delete/&lt;type&gt;   | /v1/objects   | Yes               | 1
246   status/query                  | /v1/status    | Yes               | 1
247   templates/&lt;type&gt;        | /v1/templates | Yes               | 1
248   types                         | /v1/types     | Yes               | 1
249   variables                     | /v1/variables | Yes               | 1
250
251 The required actions or types can be replaced by using a wildcard match ("\*").
252
253 ### Parameters <a id="icinga2-api-parameters"></a>
254
255 Depending on the request method there are two ways of passing parameters to the request:
256
257 * JSON object as request body (all request methods other than `GET`)
258 * Query string as URL parameter (all request methods)
259
260 Reserved characters by the HTTP protocol must be [URL-encoded](https://en.wikipedia.org/wiki/Percent-encoding)
261 as query string, e.g. a space character becomes `%20`.
262
263 Example for a URL-encoded query string:
264
265     /v1/objects/hosts?filter=match(%22example.localdomain*%22,host.name)&attrs=name&attrs=state
266
267 Here are the exact same query parameters as a JSON object:
268
269     { "filter": "match(\"example.localdomain*\",host.name)", "attrs": [ "host.name", "host.state" ] }
270
271 The [match function](18-library-reference.md#global-functions-match) is available as global function
272 in Icinga 2.
273
274 ### Request Method Override <a id="icinga2-api-requests-method-override"></a>
275
276 `GET` requests do not allow you to send a request body. In case you cannot pass everything as URL
277 parameters (e.g. complex filters or JSON-encoded dictionaries) you can use the `X-HTTP-Method-Override`
278 header. This comes in handy when you are using HTTP proxies disallowing `PUT` or `DELETE` requests too.
279
280 Query an existing object by sending a `POST` request with `X-HTTP-Method-Override: GET` as request header:
281
282     $ curl -k -s -u 'root:icinga' -H 'Accept: application/json' -X POST -H 'X-HTTP-Method-Override: GET' 'https://localhost:5665/v1/objects/hosts'
283
284 Delete an existing object by sending a `POST` request with `X-HTTP-Method-Override: DELETE` as request header:
285
286     $ curl -k -s -u 'root:icinga' -H 'Accept: application/json' -X POST -H 'X-HTTP-Method-Override: DELETE' 'https://localhost:5665/v1/objects/hosts/example.localdomain'
287
288 ### Filters <a id="icinga2-api-filters"></a>
289
290 #### Simple Filters <a id="icinga2-api-simple-filters"></a>
291
292 By default actions and queries operate on all objects unless further restricted by the user. For
293 example, the following query returns all `Host` objects:
294
295     https://localhost:5665/v1/objects/hosts
296
297 If you're only interested in a single object, you can limit the output to that object by specifying its name:
298
299     https://localhost:5665/v1/objects/hosts?host=localhost
300
301 **The name of the URL parameter is the lower-case version of the type the query applies to.** For
302 example, for `Host` objects the URL parameter therefore is `host`, for `Service` objects it is
303 `service` and so on.
304
305 You can also specify multiple objects:
306
307     https://localhost:5665/v1/objects/hosts?hosts=first-host&hosts=second-host
308
309 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.
310
311 When specifying names for objects which have composite names like for example services the
312 full name has to be used:
313
314     https://localhost:5665/v1/objects/services?service=localhost!ping6
315
316 The full name of an object can be obtained by looking at the `__name` attribute.
317
318 #### Advanced Filters <a id="icinga2-api-advanced-filters"></a>
319
320 Most of the information provided in this chapter applies to both permission filters (as used when
321 configuring `ApiUser` objects) and filters specified in queries.
322
323 Advanced filters allow users to filter objects using lambda expressions. The syntax for these filters is the same like for [apply rule expressions](03-monitoring-basics.md#using-apply-expressions).
324
325 > **Note**
326 >
327 > Filters used as URL parameter must be URL-encoded. The following examples
328 > are **not URL-encoded** for better readability.
329
330 Example matching all services in NOT-OK state:
331
332     https://localhost:5665/v1/objects/services?filter=service.state!=ServiceOK
333
334 Example [matching](18-library-reference.md#global-functions-match) all hosts by a name string pattern:
335
336     https://localhost:5665/v1/objects/hosts?filter=match("example.localdomain*",host.name)
337
338 Example for all hosts which are in the host group `linux-servers`:
339
340     https://localhost:5665/v1/objects/hosts?filter="linux-servers" in host.groups
341
342 User-specified filters are run in a sandbox environment which ensures that filters cannot
343 modify Icinga's state, for example object attributes or global variables.
344
345 When querying objects of a specific type the filter expression is evaluated for each object
346 of that type. The object is made available to the filter expression as a variable whose name
347 is the lower-case version of the object's type name.
348
349 For example when querying objects of type `Host` the variable in the filter expression is named
350 `host`. Additionally related objects such as the host's check command are also made available
351 (e.g., via the `check_command` variable). The variable names are the exact same as for the `joins`
352 query parameter; see [object query joins](12-icinga2-api.md#icinga2-api-config-objects-query-joins)
353 for details.
354
355 The object is also made available via the `obj` variable. This makes it easier to build
356 filters which can be used for more than one object type (e.g., for permissions).
357
358 Some queries can be performed for more than just one object type. One example is the 'reschedule-check'
359 action which can be used for both hosts and services. When using advanced filters you will also have to specify the
360 type using the `type` parameter:
361
362     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/reschedule-check' \
363     -d '{ "type": "Service", "filter": "service.name==\"ping6\"", "pretty": true }'
364
365 When building filters you have to ensure that values such as
366 `"linux-servers"` are escaped properly according to the rules of the Icinga 2 configuration
367 language.
368
369 To make using the API in scripts easier you can use the `filter_vars` attribute to specify
370 variables which should be made available to your filter expression. This way you don't have
371 to worry about escaping values:
372
373     $ curl -k -s -u 'root:icinga' -H 'Accept: application/json' -H 'X-HTTP-Method-Override: GET' -X POST 'https://localhost:5665/v1/objects/hosts' \
374     -d '{ "filter": "host.vars.os == os", "filter_vars": { "os": "Linux" }, "pretty": true }'
375
376 We're using [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override) here because
377 the HTTP specification does not allow message bodies for GET requests.
378
379 The `filters_vars` attribute can only be used inside the request body, but not as
380 a URL parameter because there is no way to specify a dictionary in a URL.
381
382 ## Config Objects <a id="icinga2-api-config-objects"></a>
383
384 Provides methods to manage configuration objects:
385
386 * [creating objects](12-icinga2-api.md#icinga2-api-config-objects-create)
387 * [querying objects](12-icinga2-api.md#icinga2-api-config-objects-query)
388 * [modifying objects](12-icinga2-api.md#icinga2-api-config-objects-modify)
389 * [deleting objects](12-icinga2-api.md#icinga2-api-config-objects-delete)
390
391 ### API Objects and Cluster Config Sync <a id="icinga2-api-config-objects-cluster-sync"></a>
392
393 Newly created or updated objects can be synced throughout your
394 Icinga 2 cluster. Set the `zone` attribute to the zone this object
395 belongs to and let the API and cluster handle the rest.
396
397 Objects without a zone attribute are only synced in the same zone the Icinga instance belongs to.
398
399 > **Note**
400 >
401 > Cluster nodes must accept configuration for creating, modifying
402 > and deleting objects. Ensure that `accept_config` is set to `true`
403 > in the [ApiListener](09-object-types.md#objecttype-apilistener) object
404 > on each node.
405
406 If you add a new cluster instance, or reconnect an instance which has been offline
407 for a while, Icinga 2 takes care of the initial object sync for all objects
408 created by the API.
409
410 ### Querying Objects <a id="icinga2-api-config-objects-query"></a>
411
412 You can request information about configuration objects by sending
413 a `GET` query to the `/v1/objects/<type>` URL endpoint. `<type` has
414 to be replaced with the plural name of the object type you are interested
415 in:
416
417     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/objects/hosts'
418
419 A list of all available configuration types is available in the
420 [object types](09-object-types.md#object-types) chapter.
421
422 The following URL parameters are available:
423
424   Parameters | Type         | Description
425   -----------|--------------|----------------------------
426   attrs      | Array        | **Optional.** Limited attribute list in the output.
427   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`).
428   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.
429
430 In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) may be provided.
431
432 Instead of using a filter you can optionally specify the object name in the
433 URL path when querying a single object. For objects with composite names
434 (e.g. services) the full name (e.g. `example.localdomain!http`) must be specified:
435
436     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/objects/services/example.localdomain!http'
437
438 You can limit the output to specific attributes using the `attrs` URL parameter:
439
440     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/objects/hosts/example.localdomain?attrs=name&attrs=address&pretty=1'
441     {
442         "results": [
443             {
444                 "attrs": {
445                     "name": "example.localdomain"
446                     "address": "192.168.1.1"
447                 },
448                 "joins": {},
449                 "meta": {},
450                 "name": "example.localdomain",
451                 "type": "Host"
452             }
453         ]
454     }
455
456 #### Object Queries Result <a id="icinga2-api-config-objects-query-result"></a>
457
458 Each response entry in the results array contains the following attributes:
459
460   Attribute  | Type       | Description
461   -----------|------------|--------------
462   name       | String     | Full object name.
463   type       | String     | Object type.
464   attrs      | Dictionary | Object attributes (can be filtered using the URL parameter `attrs`).
465   joins      | Dictionary | [Joined object types](12-icinga2-api.md#icinga2-api-config-objects-query-joins) as key, attributes as nested dictionary. Disabled by default.
466   meta       | Dictionary | Contains `used_by` object references. Disabled by default, enable it using `?meta=used_by` as URL parameter.
467
468 #### Object Query Joins <a id="icinga2-api-config-objects-query-joins"></a>
469
470 Icinga 2 knows about object relations. For example it can optionally return
471 information about the host when querying service objects.
472
473 The following query retrieves all host attributes:
474
475     https://localhost:5665/v1/objects/services?joins=host
476
477 Instead of requesting all host attributes you can also limit the output to specific
478 attributes:
479
480     https://localhost:5665/v1/objects/services?joins=host.name&joins=host.address
481
482 You can request that all available joins are returned in the result set by using
483 the `all_joins` query parameter.
484
485     https://localhost:5665/v1/objects/services?all_joins=1
486
487 > **Note**
488 >
489 > For performance reasons you should only request attributes which your application
490 > requires.
491
492 The following joins are available:
493
494   Object Type  | Object Relations (`joins` prefix name)
495   -------------|------------------------------------------
496   Service      | host, check\_command, check\_period, event\_command, command\_endpoint
497   Host         | check\_command, check\_period, event\_command, command\_endpoint
498   Notification | host, service, command, period
499   Dependency   | child\_host, child\_service, parent\_host, parent\_service, period
500   User         | period
501   Zones        | parent
502
503 Here's an example that retrieves all service objects for hosts which have had their `os`
504 custom attribute set to `Linux`. The result set contains the `display_name` and `check_command`
505 attributes for the service. The query also returns the host's `name` and `address` attribute
506 via a join:
507
508     $ 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'
509
510     {
511         "results": [
512             {
513                 "attrs": {
514                     "check_command": "ping4",
515                     "display_name": "ping4"
516                 },
517                 "joins": {
518                     "host": {
519                         "address": "192.168.1.1",
520                         "name": "example.localdomain"
521                     }
522                 },
523                 "meta": {},
524                 "name": "example.localdomain!ping4",
525                 "type": "Service"
526             },
527             {
528                 "attrs": {
529                     "check_command": "ssh",
530                     "display_name": "ssh"
531                 },
532                 "joins": {
533                     "host": {
534                         "address": "192.168.1.1",
535                         "name": "example.localdomain"
536                     }
537                 },
538                 "meta": {},
539                 "name": "example.localdomain!ssh",
540                 "type": "Service"
541             }
542         ]
543     }
544
545 In case you want to fetch all [comments](09-object-types.md#objecttype-comment)
546 for hosts and services, you can use the following query URL (similar example
547 for downtimes):
548
549     https://localhost:5665/v1/objects/comments?joins=host&joins=service
550
551 This is another example for listing all service objects which are unhandled problems (state is not OK
552 and no downtime or acknowledgement set). We're using [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override)
553 here because we want to pass all query attributes in the request body.
554
555     $ curl -k -s -u root:icinga -H 'Accept: application/json' -H 'X-HTTP-Method-Override: GET' -X POST 'https://127.0.0.1:5665/v1/objects/services' \
556     -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 }'
557
558     {
559         "results": [
560             {
561                 "attrs": {
562                     "acknowledgement": 0.0,
563                     "downtime_depth": 0.0,
564                     "name": "10807-service",
565                     "state": 3.0
566                 },
567                 "joins": {
568                     "host": {
569                         "address": "",
570                         "name": "10807-host"
571                     }
572                 },
573                 "meta": {},
574                 "name": "10807-host!10807-service",
575                 "type": "Service"
576             }
577         ]
578     }
579
580 In order to list all acknowledgements without expire time, you query the `/v1/objects/comments`
581 URL endpoint with `joins` and `filter` request parameters using the [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override)
582 method:
583
584     $ curl -k -s -u root:icinga -H 'Accept: application/json' -H 'X-HTTP-Method-Override: GET' -X POST 'https://localhost:5665/v1/objects/comments' \
585     -d '{ "joins": [ "service.name", "service.acknowledgement", "service.acknowledgement_expiry" ], "attrs": [ "author", "text" ], "filter": "service.acknowledgement!=0 && service.acknowledgement_expiry==0", "pretty": true }'
586
587     {
588         "results": [
589             {
590                 "attrs": {
591                     "author": "icingaadmin",
592                     "text": "maintenance work"
593                 },
594                 "joins": {
595                     "service": {
596                         "__name": "example.localdomain!disk /",
597                         "acknowledgement": 1.0,
598                         "acknowledgement_expiry": 0.0
599                     }
600                 },
601                 "meta": {},
602                 "name": "example.localdomain!disk /!example.localdomain-1495457222-0",
603                 "type": "Comment"
604             }
605         ]
606     }
607
608 ### Creating Config Objects <a id="icinga2-api-config-objects-create"></a>
609
610 New objects must be created by sending a PUT request. The following
611 parameters need to be passed inside the JSON body:
612
613   Parameters        | Type         | Description
614   ------------------|--------------|--------------------------
615   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)-
616   attrs             | Dictionary   | **Required.** Set specific object attributes for this [object type](09-object-types.md#object-types).
617   ignore\_on\_error | Boolean      | **Optional.** Ignore object creation errors and return an HTTP 200 status instead.
618
619 The object name must be specified as part of the URL path. For objects with composite names (e.g. services)
620 the full name (e.g. `example.localdomain!http`) must be specified.
621
622 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):
623
624     "attrs": { "vars.os": "Linux" }
625
626 Example for creating the new host object `example.localdomain`:
627
628     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X PUT 'https://localhost:5665/v1/objects/hosts/example.localdomain' \
629     -d '{ "templates": [ "generic-host" ], "attrs": { "address": "192.168.1.1", "check_command": "hostalive", "vars.os" : "Linux" }, "pretty": true }'
630     {
631         "results": [
632             {
633                 "code": 200.0,
634                 "status": "Object was created."
635             }
636         ]
637     }
638
639 If the configuration validation fails, the new object will not be created and the response body
640 contains a detailed error message. The following example is missing the `check_command` attribute
641 which is required for host objects:
642
643     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X PUT 'https://localhost:5665/v1/objects/hosts/example.localdomain' \
644     -d '{ "attrs": { "address": "192.168.1.1", "vars.os" : "Linux" }, "pretty": true }'
645     {
646         "results": [
647             {
648                 "code": 500.0,
649                 "errors": [
650                     "Error: Validation failed for object 'example.localdomain' of type 'Host'; Attribute 'check_command': Attribute must not be empty."
651                 ],
652                 "status": "Object could not be created."
653             }
654         ]
655     }
656
657 Service objects must be created using their full name ("hostname!servicename") referencing an existing host object:
658
659     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X PUT 'https://localhost:5665/v1/objects/services/example.localdomain!realtime-load' \
660     -d '{ "templates": [ "generic-service" ], "attrs": { "check_command": "load", "check_interval": 1,"retry_interval": 1 } }'
661
662
663 Example for a new CheckCommand object:
664
665     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X PUT 'https://localhost:5665/v1/objects/checkcommands/mytest' \
666     -d '{ "templates": [ "plugin-check-command" ], "attrs": { "command": [ "/usr/local/sbin/check_http" ], "arguments": { "-I": "$mytest_iparam$" } } }'
667
668
669 ### Modifying Objects <a id="icinga2-api-config-objects-modify"></a>
670
671 Existing objects must be modified by sending a `POST` request. The following
672 parameters need to be passed inside the JSON body:
673
674   Parameters | Type       | Description
675   -----------|------------|---------------------------
676   attrs      | Dictionary | **Required.** Set specific object attributes for this [object type](09-object-types.md#object-types).
677
678 In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) should be provided.
679
680 > **Note**:
681 >
682 > Modified attributes do not trigger a re-evaluation of existing
683 > static [apply rules](03-monitoring-basics.md#using-apply) and [group assignments](03-monitoring-basics.md#group-assign-intro).
684 > Delete and re-create the objects if you require such changes.
685 >
686 > Furthermore you cannot modify templates which have already been resolved
687 > during [object creation](12-icinga2-api.md#icinga2-api-config-objects-create).
688 > There are attributes which can only be set for [PUT requests](12-icinga2-api.md#icinga2-api-config-objects-create) such as `groups`
689 > 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.
690
691 If attributes are of the Dictionary type, you can also use the indexer format:
692
693     "attrs": { "vars.os": "Linux" }
694
695 The following example updates the `address` attribute and the custom attribute `os` for the `example.localdomain` host:
696
697     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/objects/hosts/example.localdomain' \
698     -d '{ "attrs": { "address": "192.168.1.2", "vars.os" : "Windows" }, "pretty": true }'
699     {
700         "results": [
701             {
702                 "code": 200.0,
703                 "name": "example.localdomain",
704                 "status": "Attributes updated.",
705                 "type": "Host"
706             }
707         ]
708     }
709
710
711 ### Deleting Objects <a id="icinga2-api-config-objects-delete"></a>
712
713 You can delete objects created using the API by sending a `DELETE`
714 request.
715
716   Parameters | Type    | Description
717   -----------|---------|---------------
718   cascade    | Boolean |  **Optional.** Delete objects depending on the deleted objects (e.g. services on a host).
719
720 In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) should be provided.
721
722 Example for deleting the host object `example.localdomain`:
723
724     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X DELETE 'https://localhost:5665/v1/objects/hosts/example.localdomain?cascade=1&pretty=1'
725     {
726         "results": [
727             {
728                 "code": 200.0,
729                 "name": "example.localdomain",
730                 "status": "Object was deleted.",
731                 "type": "Host"
732             }
733         ]
734     }
735
736 ## Config Templates <a id="icinga2-api-config-templates"></a>
737
738 Provides methods to manage configuration templates:
739
740 * [querying templates](12-icinga2-api.md#icinga2-api-config-templates-query)
741
742 Creation, modification and deletion of templates at runtime is not supported.
743
744 ### Querying Templates <a id="icinga2-api-config-templates-query"></a>
745
746 You can request information about configuration templates by sending
747 a `GET` query to the `/v1/templates/<type>` URL endpoint. `<type` has
748 to be replaced with the plural name of the object type you are interested
749 in:
750
751     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/templates/hosts'
752
753 A list of all available configuration types is available in the
754 [object types](09-object-types.md#object-types) chapter.
755
756 A [filter](12-icinga2-api.md#icinga2-api-filters) may be provided for this query type. The
757 template object can be accessed in the filter using the `tmpl` variable. In this
758 example the [match function](18-library-reference.md#global-functions-match) is used to
759 check a wildcard string pattern against `tmpl.name`.
760 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)
761 here.
762
763     $ curl -k -s -u root:icinga -H 'Accept: application/json' -H 'X-HTTP-Method-Override: GET' -X POST 'https://localhost:5661/v1/templates/hosts' \
764     -d '{ "filter": "match(\"g*\", tmpl.name)" }'
765
766 Instead of using a filter you can optionally specify the template name in the
767 URL path when querying a single object:
768
769     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/templates/hosts/generic-host'
770
771 The result set contains the type, name as well as the location of the template.
772
773 ## Variables <a id="icinga2-api-variables"></a>
774
775 Provides methods to manage global variables:
776
777 * [querying variables](12-icinga2-api.md#icinga2-api-variables-query)
778
779 ### Querying Variables <a id="icinga2-api-variables-query"></a>
780
781 You can request information about global variables by sending
782 a `GET` query to the `/v1/variables/` URL endpoint:
783
784     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/variables'
785
786 A [filter](12-icinga2-api.md#icinga2-api-filters) may be provided for this query type. The
787 variable information object can be accessed in the filter using the `variable` variable.
788 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)
789 here.
790
791     $ curl -k -s -u root:icinga -H 'Accept: application/json' -H 'X-HTTP-Method-Override: GET' -X POST 'https://localhost:5661/v1/variables' \
792     -d '{ "filter": "variable.type in [ \"String\", \"Number\" ]" }'
793
794 Instead of using a filter you can optionally specify the variable name in the
795 URL path when querying a single variable:
796
797     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/variables/PrefixDir'
798
799 The result set contains the type, name and value of the global variable.
800
801 ## Actions <a id="icinga2-api-actions"></a>
802
803 There are several actions available for Icinga 2 provided by the `/v1/actions`
804 URL endpoint. You can run actions by sending a `POST` request.
805
806 In case you have been using the [external commands](14-features.md#external-commands)
807 in the past, the API actions provide a similar interface with filter
808 capabilities for some of the more common targets which do not directly change
809 the configuration.
810
811 All actions return a 200 `OK` or an appropriate error code for each
812 action performed on each object matching the supplied filter.
813
814 Actions which affect the Icinga Application itself such as disabling
815 notification on a program-wide basis must be applied by updating the
816 [IcingaApplication object](12-icinga2-api.md#icinga2-api-config-objects)
817 called `app`.
818
819     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/objects/icingaapplications/app' -d '{ "attrs": { "enable_notifications": false } }'
820
821 ### process-check-result <a id="icinga2-api-actions-process-check-result"></a>
822
823 Process a check result for a host or a service.
824
825 Send a `POST` request to the URL endpoint `/v1/actions/process-check-result`.
826
827   Parameter         | Type         | Description
828   ------------------|--------------|--------------
829   exit\_status      | Number       | **Required.** For services: 0=OK, 1=WARNING, 2=CRITICAL, 3=UNKNOWN, for hosts: 0=OK, 1=CRITICAL.
830   plugin\_output    | String       | **Required.** One or more lines of the plugin main output. Does **not** contain the performance data.
831   performance\_data | Array|String | **Optional.** The performance data as array of strings. The raw performance data string can be used too.
832   check\_command    | Array        | **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.
833   check\_source     | String       | **Optional.** Usually the name of the `command_endpoint`
834   execution\_start  | Timestamp    | **Optional.** The timestamp where a script/process started its execution.
835   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.
836   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.
837
838 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`.
839
840 Example for the service `passive-ping6`:
841
842     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/process-check-result?service=example.localdomain!passive-ping6' \
843     -d '{ "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 }'
844
845     {
846         "results": [
847             {
848                 "code": 200.0,
849                 "status": "Successfully processed check result for object 'localdomain!passive-ping6'."
850             }
851         ]
852     }
853
854 Example for using the `Host` type and filter by the host name:
855
856     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/process-check-result' \
857     -d '{ "filter": "host.name==\"example.localdomain\"", "type": "Host", "exit_status": 1, "plugin_output": "Host is not available." }'
858
859 You can avoid URL encoding of white spaces in object names by using the `filter` attribute in the request body.
860
861 > **Note**
862 >
863 > Multi-line plugin output requires the following format: The first line is treated as `short` plugin output corresponding
864 > to the first line of the plugin output. Subsequent lines are treated as `long` plugin output. Please note that the
865 > performance data is separated from the plugin output and has to be passed as `performance_data` attribute.
866
867 ### reschedule-check <a id="icinga2-api-actions-reschedule-check"></a>
868
869 Reschedule a check for hosts and services. The check can be forced if required.
870
871 Send a `POST` request to the URL endpoint `/v1/actions/reschedule-check`.
872
873   Parameter    | Type      | Description
874   -------------|-----------|--------------
875   next\_check  | Timestamp | **Optional.** The next check will be run at this time. If omitted, the current time is used.
876   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.
877
878 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`.
879
880 The example reschedules all services with the name "ping6" to immediately perform a check
881 (`next_check` default), ignoring any time periods or whether active checks are
882 allowed for the service (`force=true`).
883
884     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/reschedule-check' \
885     -d '{ "type": "Service", "filter": "service.name==\"ping6\"", "force": true, "pretty": true }'
886
887     {
888         "results": [
889             {
890                 "code": 200.0,
891                 "status": "Successfully rescheduled check for object 'example.localdomain!ping6'."
892             }
893         ]
894     }
895
896
897 ### send-custom-notification <a id="icinga2-api-actions-send-custom-notification"></a>
898
899 Send a custom notification for hosts and services. This notification
900 type can be forced being sent to all users.
901
902 Send a `POST` request to the URL endpoint `/v1/actions/send-custom-notification`.
903
904   Parameter | Type    | Description
905   ----------|---------|--------------
906   author    | String  | **Required.** Name of the author, may be empty.
907   comment   | String  | **Required.** Comment text, may be empty.
908   force     | Boolean | **Optional.** Default: false. If true, the notification is sent regardless of downtimes or whether notifications are enabled or not.
909
910 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`.
911
912 Example for a custom host notification announcing a global maintenance to
913 host owners:
914
915     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/send-custom-notification' \
916     -d '{ "type": "Host", "author": "icingaadmin", "comment": "System is going down for maintenance", "force": true, "pretty": true }'
917
918     {
919         "results": [
920             {
921                 "code": 200.0,
922                 "status": "Successfully sent custom notification for object 'host0'."
923             },
924             {
925                 "code": 200.0,
926                 "status": "Successfully sent custom notification for object 'host1'."
927             }
928     }
929
930 ### delay-notification <a id="icinga2-api-actions-delay-notification"></a>
931
932 Delay notifications for a host or a service.
933 Note that this will only have an effect if the service stays in the same problem
934 state that it is currently in. If the service changes to another state, a new
935 notification may go out before the time you specify in the `timestamp` argument.
936
937 Send a `POST` request to the URL endpoint `/v1/actions/delay-notification`.
938
939   Parameter | Type      | Description
940   ----------|-----------|--------------
941   timestamp | Timestamp | **Required.** Delay notifications until this timestamp.
942
943 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`.
944
945 Example:
946
947     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/delay-notification' \
948     -d '{ "type": "Service", "timestamp": 1446389894, "pretty": true }'
949
950     {
951         "results": [
952             {
953                 "code": 200.0,
954                 "status": "Successfully delayed notifications for object 'host0!service0'."
955             },
956             {
957                 "code": 200.0,
958                 "status": "Successfully delayed notifications for object 'host1!service1'."
959             }
960     }
961
962 ### acknowledge-problem <a id="icinga2-api-actions-acknowledge-problem"></a>
963
964 Allows you to acknowledge the current problem for hosts or services. By
965 acknowledging the current problem, future notifications (for the same state if `sticky` is set to `false`)
966 are disabled.
967
968 Send a `POST` request to the URL endpoint `/v1/actions/acknowledge-problem`.
969
970   Parameter            | Type      | Description
971   ---------------------|-----------|--------------
972   author               | String    | **Required.** Name of the author, may be empty.
973   comment              | String    | **Required.** Comment text, may be empty.
974   expiry               | Timestamp | **Optional.** Whether the acknowledgement will be removed at the timestamp.
975   sticky               | Boolean   | **Optional.** Whether the acknowledgement will be set until the service or host fully recovers. Defaults to `false`.
976   notify               | Boolean   | **Optional.** Whether a notification of the `Acknowledgement` type will be sent. Defaults to `false`.
977   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`.
978
979 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`.
980
981 The following example acknowledges all services which are in a hard critical state and sends out
982 a notification for them:
983
984     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/acknowledge-problem?type=Service&filter=service.state==2&service.state_type=1' \
985     -d '{ "author": "icingaadmin", "comment": "Global outage. Working on it.", "notify": true, "pretty": true }'
986
987     {
988         "results": [
989             {
990                 "code": 200.0,
991                 "status": "Successfully acknowledged problem for object 'example2.localdomain!ping4'."
992             },
993             {
994                 "code": 200.0,
995                 "status": "Successfully acknowledged problem for object 'example.localdomain!ping4'."
996             }
997     }
998
999
1000 ### remove-acknowledgement <a id="icinga2-api-actions-remove-acknowledgement"></a>
1001
1002 Removes the acknowledgements for services or hosts. Once the acknowledgement has
1003 been removed notifications will be sent out again.
1004
1005 Send a `POST` request to the URL endpoint `/v1/actions/remove-acknowledgement`.
1006
1007 A [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`.
1008
1009 The example removes all service acknowledgements:
1010
1011     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/remove-acknowledgement?type=Service&pretty=1'
1012
1013     {
1014         "results": [
1015             {
1016                 "code": 200.0,
1017                 "status": "Successfully removed acknowledgement for object 'host0!service0'."
1018             },
1019             {
1020                 "code": 200.0,
1021                 "status": "Successfully removed acknowledgement for object 'example2.localdomain!aws-health'."
1022             }
1023     }
1024
1025 ### add-comment <a id="icinga2-api-actions-add-comment"></a>
1026
1027 Adds a `comment` from an `author` to services or hosts.
1028
1029 Send a `POST` request to the URL endpoint `/v1/actions/add-comment`.
1030
1031   Parameter | Type   | Description
1032   ----------|--------|--------------
1033   author    | string | **Required.** Name of the author, may be empty.
1034   comment   | string | **Required.** Comment text, may be empty.
1035
1036 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`.
1037
1038 The following example adds a comment for all `ping4` services:
1039
1040     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/add-comment?type=Service&filter=service.name==%22ping4%22' -d '{ "author": "icingaadmin", "comment": "Troubleticket #123456789 opened.", "pretty": true }'
1041     {
1042         "results": [
1043             {
1044                 "code": 200.0,
1045                 "legacy_id": 26.0,
1046                 "name": "example.localdomain!ping4!example.localdomain-1446824161-0",
1047                 "status": "Successfully added comment 'example.localdomain!ping4!example.localdomain-1446824161-0' for object 'example.localdomain!ping4'."
1048             },
1049             {
1050                 "code": 200.0,
1051                 "legacy_id": 27.0,
1052                 "name": "example2.localdomain!ping4!example.localdomain-1446824161-1",
1053                 "status": "Successfully added comment 'example2.localdomain!ping4!example.localdomain-1446824161-1' for object 'example2.localdomain!ping4'."
1054             }
1055         ]
1056     }
1057
1058 ### remove-comment <a id="icinga2-api-actions-remove-comment"></a>
1059
1060 Remove the comment using its `name` attribute , returns `OK` if the
1061 comment did not exist.
1062 **Note**: This is **not** the legacy ID but the comment name returned by
1063 Icinga 2 when [adding a comment](12-icinga2-api.md#icinga2-api-actions-add-comment).
1064
1065 Send a `POST` request to the URL endpoint `/v1/actions/remove-comment`.
1066
1067 A [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host`, `Service` and `Comment`.
1068
1069 Example for a simple filter using the `comment` URL parameter:
1070
1071     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/remove-comment?comment=example2.localdomain!ping4!mbmif.local-1446986367-0&pretty=1'
1072     {
1073         "results": [
1074             {
1075                 "code": 200.0,
1076                 "status": "Successfully removed comment 'example2.localdomain!ping4!mbmif.local-1446986367-0'."
1077             }
1078         ]
1079     }
1080
1081 Example for removing all service comments using a service name filter for `ping4`:
1082
1083     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/remove-comment?filter=service.name==%22ping4%22&type=Service&pretty=1'
1084     {
1085         "results": [
1086             {
1087                 "code": 200.0,
1088                 "status": "Successfully removed all comments for object 'example2.localdomain!ping4'."
1089             },
1090             {
1091                 "code": 200.0,
1092                 "status": "Successfully removed all comments for object 'example.localdomain!ping4'."
1093             }
1094         ]
1095     }
1096
1097
1098 ### schedule-downtime <a id="icinga2-api-actions-schedule-downtime"></a>
1099
1100 Schedule a downtime for hosts and services.
1101
1102 Send a `POST` request to the URL endpoint `/v1/actions/schedule-downtime`.
1103
1104   Parameter     | Type      | Description
1105   --------------|-----------|--------------
1106   author        | String    | **Required.** Name of the author.
1107   comment       | String    | **Required.** Comment text.
1108   start\_time   | Timestamp | **Required.** Timestamp marking the beginning of the downtime.
1109   end\_time     | Timestamp | **Required.** Timestamp marking the end of the downtime.
1110   fixed         | Boolean   | **Optional.** Defaults to `true`. If true, the downtime is `fixed` otherwise `flexible`. See [downtimes](08-advanced-topics.md#downtimes) for more information.
1111   duration      | Number    | **Required for flexible downtimes.** Duration of the downtime in seconds if `fixed` is set to false.
1112   trigger\_name | String    | **Optional.** Sets the trigger for a triggered downtime. See [downtimes](08-advanced-topics.md#downtimes) for more information on triggered downtimes.
1113   child\_options | Number   | **Optional.** Schedule child downtimes. `0` does not do anything, `1` schedules child downtimes triggered by this downtime, `2` schedules non-triggered downtimes. Defaults to `0`.
1114
1115 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`.
1116
1117 Example:
1118
1119     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/schedule-downtime?type=Service&filter=service.name==%22ping4%22' -d '{ "start_time": 1446388806, "end_time": 1446389806, "duration": 1000, "author": "icingaadmin", "comment": "IPv4 network maintenance", "pretty": true }'
1120     {
1121         "results": [
1122             {
1123                 "code": 200.0,
1124                 "legacy_id": 2.0,
1125                 "name": "example2.localdomain!ping4!example.localdomain-1446822004-0",
1126                 "status": "Successfully scheduled downtime 'example2.localdomain!ping4!example.localdomain-1446822004-0' for object 'example2.localdomain!ping4'."
1127             },
1128             {
1129                 "code": 200.0,
1130                 "legacy_id": 3.0,
1131                 "name": "example.localdomain!ping4!example.localdomain-1446822004-1",
1132                 "status": "Successfully scheduled downtime 'example.localdomain!ping4!example.localdomain-1446822004-1' for object 'example.localdomain!ping4'."
1133             }
1134         ]
1135     }
1136
1137 ### remove-downtime <a id="icinga2-api-actions-remove-downtime"></a>
1138
1139 Remove the downtime using its `name` attribute , returns `OK` if the
1140 downtime did not exist.
1141 **Note**: This is **not** the legacy ID but the downtime name returned by
1142 Icinga 2 when [scheduling a downtime](12-icinga2-api.md#icinga2-api-actions-schedule-downtime).
1143
1144 Send a `POST` request to the URL endpoint `/v1/actions/remove-downtime`.
1145
1146 A [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host`, `Service` and `Downtime`.
1147
1148 Example for a simple filter using the `downtime` URL parameter:
1149
1150     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/remove-downtime?downtime=example.localdomain!ping4!mbmif.local-1446979168-6&pretty=1'
1151     {
1152         "results": [
1153             {
1154                 "code": 200.0,
1155                 "status": "Successfully removed downtime 'example.localdomain!ping4!mbmif.local-1446979168-6'."
1156             }
1157         ]
1158     }
1159
1160 Example for removing all host downtimes using a host name filter for `example.localdomain`:
1161
1162     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/remove-downtime?filter=host.name==%22example.localdomain%22&type=Host&pretty=1'
1163     {
1164         "results": [
1165             {
1166                 "code": 200.0,
1167                 "status": "Successfully removed all downtimes for object 'example.localdomain'."
1168             }
1169         ]
1170     }
1171
1172 Example for removing a downtime from a host but not the services filtered by the author name. This example uses
1173 filter variables explained in the [advanced filters](12-icinga2-api.md#icinga2-api-advanced-filters) chapter.
1174
1175     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/remove-downtime' \
1176             -d $'{
1177       "type": "Downtime",
1178       "filter": "host.name == filterHost && !service && downtime.author == filterAuthor",
1179       "filter_vars": {
1180         "filterHost": "example.localdomain",
1181         "filterAuthor": "icingaadmin"
1182       },
1183       "pretty": true
1184     }'
1185
1186     {
1187         "results": [
1188             {
1189                 "code": 200.0,
1190                 "status": "Successfully removed downtime 'example.localdomain!mbmif.local-1463043129-3'."
1191             }
1192         ]
1193     }
1194
1195 ### shutdown-process <a id="icinga2-api-actions-shutdown-process"></a>
1196
1197 Shuts down Icinga2. May or may not return.
1198
1199 Send a `POST` request to the URL endpoint `/v1/actions/shutdown-process`.
1200
1201 This action does not support a target type or filter.
1202
1203 Example:
1204
1205     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/shutdown-process?pretty=1'
1206
1207     {
1208         "results": [
1209             {
1210                 "code": 200.0,
1211                 "status": "Shutting down Icinga 2."
1212             }
1213         ]
1214     }
1215
1216 ### restart-process <a id="icinga2-api-actions-restart-process"></a>
1217
1218 Restarts Icinga2. May or may not return.
1219
1220 Send a `POST` request to the URL endpoint `/v1/actions/restart-process`.
1221
1222 This action does not support a target type or filter.
1223
1224 Example:
1225
1226     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/restart-process?pretty=1'
1227
1228     {
1229         "results": [
1230             {
1231                 "code": 200.0,
1232                 "status": "Restarting Icinga 2."
1233             }
1234         ]
1235     }
1236
1237 ### generate-ticket <a id="icinga2-api-actions-generate-ticket"></a>
1238
1239 Generates a PKI ticket for [CSR auto-signing](06-distributed-monitoring.md#distributed-monitoring-setup-csr-auto-signing).
1240 This can be used in combination with satellite/client setups requesting this ticket number.
1241
1242 Send a `POST` request to the URL endpoint `/v1/actions/generate-ticket`.
1243
1244   Parameter     | Type      | Description
1245   --------------|-----------|--------------
1246   cn            | String    | **Required.** The host's common name for which the ticket should be geenerated.
1247
1248 Example:
1249
1250     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/generate-ticket' \
1251     -d '{ "cn": "icinga2-client1.localdomain", "pretty": true }'
1252     {
1253         "results": [
1254             {
1255                 "code": 200.0,
1256                 "status": "Generated PKI ticket '4f75d2ecd253575fe9180938ebff7cbca262f96e' for common name 'icinga2-client1.localdomain'.",
1257                 "ticket": "4f75d2ecd253575fe9180938ebff7cbca262f96e"
1258             }
1259         ]
1260     }
1261
1262
1263 ## Event Streams <a id="icinga2-api-event-streams"></a>
1264
1265 You can subscribe to event streams by sending a `POST` request to the URL endpoint `/v1/events`.
1266 The following parameters need to be specified (either as URL parameters or in a JSON-encoded message body):
1267
1268   Parameter  | Type         | Description
1269   -----------|--------------|-------------
1270   types      | Array        | **Required.** Event type(s). Multiple types as URL parameters are supported.
1271   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.
1272   filter     | String       | **Optional.** Filter for specific event attributes using [filter expressions](12-icinga2-api.md#icinga2-api-filters).
1273
1274 ### Event Stream Types <a id="icinga2-api-event-streams-types"></a>
1275
1276 The following event stream types are available:
1277
1278   Type                   | Description
1279   -----------------------|--------------
1280   CheckResult            | Check results for hosts and services.
1281   StateChange            | Host/service state changes.
1282   Notification           | Notification events including notified users for hosts and services.
1283   AcknowledgementSet     | Acknowledgement set on hosts and services.
1284   AcknowledgementCleared | Acknowledgement cleared on hosts and services.
1285   CommentAdded           | Comment added for hosts and services.
1286   CommentRemoved         | Comment removed for hosts and services.
1287   DowntimeAdded          | Downtime added for hosts and services.
1288   DowntimeRemoved        | Downtime removed for hosts and services.
1289   DowntimeStarted        | Downtime started for hosts and services.
1290   DowntimeTriggered      | Downtime triggered for hosts and services.
1291
1292 Note: Each type requires [API permissions](12-icinga2-api.md#icinga2-api-permissions)
1293 being set.
1294
1295 Example for all downtime events:
1296
1297     &types=DowntimeAdded&types=DowntimeRemoved&types=DowntimeTriggered
1298
1299 #### <a id="icinga2-api-event-streams-type-checkresult"></a> Event Stream Type: CheckResult
1300
1301   Name          | Type          | Description
1302   --------------|---------------|--------------------------
1303   type          | String        | Event type `CheckResult`.
1304   timestamp     | Timestamp     | Unix timestamp when the event happened.
1305   host          | String        | [Host](09-object-types.md#objecttype-host) name.
1306   service       | String        | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host check result.
1307   check\_result | CheckResult   | Serialized [CheckResult](08-advanced-topics.md#advanced-value-types-checkresult) value type.
1308
1309 #### <a id="icinga2-api-event-streams-type-statechange"></a> Event Stream Type: StateChange
1310
1311   Name          | Type          | Description
1312   --------------|---------------|--------------------------
1313   type          | String        | Event type `StateChange`.
1314   timestamp     | Timestamp     | Unix timestamp when the event happened.
1315   host          | String        | [Host](09-object-types.md#objecttype-host) name.
1316   service       | String        | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host state change.
1317   state         | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state.
1318   state\_type   | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state type.
1319   check\_result | CheckResult   | Serialized [CheckResult](08-advanced-topics.md#advanced-value-types-checkresult) value type.
1320
1321 #### <a id="icinga2-api-event-streams-type-notification"></a> Event Stream Type: Notification
1322
1323   Name          | Type          | Description
1324   --------------|---------------|--------------------------
1325   type          | String        | Event type `Notification`.
1326   timestamp     | Timestamp     | Unix timestamp when the event happened.
1327   host          | String        | [Host](09-object-types.md#objecttype-host) name.
1328   service       | String        | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host notification.
1329   users         | Array         | List of notified [user](09-object-types.md#objecttype-user) names.
1330   notification\_type | String   | [$notification.type$](03-monitoring-basics.md#notification-runtime-macros) runtime macro value.
1331   author        | String        | [$notification.author$](03-monitoring-basics.md#notification-runtime-macros) runtime macro value.
1332   text          | String        | [$notification.comment$](03-monitoring-basics.md#notification-runtime-macros) runtime macro value.
1333   check\_result | CheckResult   | Serialized [CheckResult](08-advanced-topics.md#advanced-value-types-checkresult) value type.
1334
1335 #### <a id="icinga2-api-event-streams-type-flapping"></a> Event Stream Type: Flapping
1336
1337   Name              | Type          | Description
1338   ------------------|---------------|--------------------------
1339   type              | String        | Event type `Flapping`.
1340   timestamp         | Timestamp     | Unix timestamp when the event happened.
1341   host              | String        | [Host](09-object-types.md#objecttype-host) name.
1342   service           | String        | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host flapping event.
1343   state             | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state.
1344   state\_type       | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state type.
1345   is\_flapping      | Boolean       | Whether this object is flapping.
1346   current\_flapping | Number        | Current flapping value in percent (added in 2.8).
1347   threshold\_low    | Number        | Low threshold in percent (added in 2.8).
1348   threshold\_high   | Number        | High threshold in percent (added in 2.8).
1349
1350 #### <a id="icinga2-api-event-streams-type-acknowledgementset"></a> Event Stream Type: AcknowledgementSet
1351
1352   Name          | Type          | Description
1353   --------------|---------------|--------------------------
1354   type          | String        | Event type `AcknowledgementSet`.
1355   timestamp     | Timestamp     | Unix timestamp when the event happened.
1356   host          | String        | [Host](09-object-types.md#objecttype-host) name.
1357   service       | String        | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host acknowledgement.
1358   state         | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state.
1359   state\_type   | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state type.
1360   author        | String        | Acknowledgement author set via [acknowledge-problem](12-icinga2-api.md#icinga2-api-actions-acknowledge-problem) action.
1361   comment       | String        | Acknowledgement comment set via [acknowledge-problem](12-icinga2-api.md#icinga2-api-actions-acknowledge-problem) action.
1362   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.
1363   notify        | Boolean       | Notifications were enabled via [acknowledge-problem](12-icinga2-api.md#icinga2-api-actions-acknowledge-problem) action.
1364   expiry        | Timestamp     | Acknowledgement expire time set via [acknowledge-problem](12-icinga2-api.md#icinga2-api-actions-acknowledge-problem) action.
1365
1366 #### <a id="icinga2-api-event-streams-type-acknowledgementcleared"></a> Event Stream Type: AcknowledgementCleared
1367
1368   Name          | Type          | Description
1369   --------------|---------------|--------------------------
1370   type          | String        | Event type `AcknowledgementCleared`.
1371   timestamp     | Timestamp     | Unix timestamp when the event happened.
1372   host          | String        | [Host](09-object-types.md#objecttype-host) name.
1373   service       | String        | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host acknowledgement.
1374   state         | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state.
1375   state\_type   | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state type.
1376
1377 #### <a id="icinga2-api-event-streams-type-commentadded"></a> Event Stream Type: CommentAdded
1378
1379   Name          | Type          | Description
1380   --------------|---------------|--------------------------
1381   type          | String        | Event type `CommentAdded`.
1382   timestamp     | Timestamp     | Unix timestamp when the event happened.
1383   comment       | Dictionary    | Serialized [Comment](09-object-types.md#objecttype-comment) object.
1384
1385 #### <a id="icinga2-api-event-streams-type-commentremoved"></a> Event Stream Type: CommentRemoved
1386
1387   Name          | Type          | Description
1388   --------------|---------------|--------------------------
1389   type          | String        | Event type `CommentRemoved`.
1390   timestamp     | Timestamp     | Unix timestamp when the event happened.
1391   comment       | Dictionary    | Serialized [Comment](09-object-types.md#objecttype-comment) object.
1392
1393 #### <a id="icinga2-api-event-streams-type-downtimeadded"></a> Event Stream Type: DowntimeAdded
1394
1395   Name          | Type          | Description
1396   --------------|---------------|--------------------------
1397   type          | String        | Event type `DowntimeAdded`.
1398   timestamp     | Timestamp     | Unix timestamp when the event happened.
1399   downtime      | Dictionary    | Serialized [Comment](09-object-types.md#objecttype-downtime) object.
1400
1401 #### <a id="icinga2-api-event-streams-type-downtimeremoved"></a> Event Stream Type: DowntimeRemoved
1402
1403   Name          | Type          | Description
1404   --------------|---------------|--------------------------
1405   type          | String        | Event type `DowntimeRemoved`.
1406   timestamp     | Timestamp     | Unix timestamp when the event happened.
1407   downtime      | Dictionary    | Serialized [Comment](09-object-types.md#objecttype-downtime) object.
1408
1409
1410 #### <a id="icinga2-api-event-streams-type-downtimestarted"></a> Event Stream Type: DowntimeStarted
1411
1412   Name          | Type          | Description
1413   --------------|---------------|--------------------------
1414   type          | String        | Event type `DowntimeStarted`.
1415   timestamp     | Timestamp     | Unix timestamp when the event happened.
1416   downtime      | Dictionary    | Serialized [Comment](09-object-types.md#objecttype-downtime) object.
1417
1418
1419 #### <a id="icinga2-api-event-streams-type-downtimetriggered"></a> Event Stream Type: DowntimeTriggered
1420
1421   Name          | Type          | Description
1422   --------------|---------------|--------------------------
1423   type          | String        | Event type `DowntimeTriggered`.
1424   timestamp     | Timestamp     | Unix timestamp when the event happened.
1425   downtime      | Dictionary    | Serialized [Comment](09-object-types.md#objecttype-downtime) object.
1426
1427
1428 ### Event Stream Filter <a id="icinga2-api-event-streams-filter"></a>
1429
1430 Event streams can be filtered by attributes using the prefix `event.`.
1431
1432 Example for the `CheckResult` type with the `exit_code` set to `2`:
1433
1434     &types=CheckResult&filter=event.check_result.exit_status==2
1435
1436 Example for the `CheckResult` type with the service [matching](18-library-reference.md#global-functions-match)
1437 the string pattern "random\*":
1438
1439     &types=CheckResult&filter=match%28%22random*%22,event.service%29
1440
1441
1442 ### Event Stream Response <a id="icinga2-api-event-streams-response"></a>
1443
1444 The event stream response is separated with new lines. The HTTP client
1445 must support long-polling and HTTP/1.1. HTTP/1.0 is not supported.
1446
1447 Example:
1448
1449     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/events?queue=michi&types=CheckResult&filter=event.check_result.exit_status==2'
1450
1451     {"check_result":{ ... },"host":"example.localdomain","service":"ping4","timestamp":1445421319.7226390839,"type":"CheckResult"}
1452     {"check_result":{ ... },"host":"example.localdomain","service":"ping4","timestamp":1445421324.7226390839,"type":"CheckResult"}
1453     {"check_result":{ ... },"host":"example.localdomain","service":"ping4","timestamp":1445421329.7226390839,"type":"CheckResult"}
1454
1455
1456 ## Status and Statistics <a id="icinga2-api-status"></a>
1457
1458 Send a `GET` request to the URL endpoint `/v1/status` to retrieve status information and statistics for Icinga 2.
1459
1460 Example:
1461
1462     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/status?pretty=1'
1463     {
1464         "results": [
1465             {
1466                 "name": "ApiListener",
1467                 "perfdata": [ ... ],
1468                 "status": [ ... ]
1469             },
1470             ...
1471             {
1472                 "name": "IcingaAplication",
1473                 "perfdata": [ ... ],
1474                 "status": [ ... ]
1475             },
1476             ...
1477         ]
1478     }
1479
1480 You can limit the output by specifying a status type in the URL, e.g. `IcingaApplication`:
1481
1482     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/status/IcingaApplication?pretty=1'
1483     {
1484         "results": [
1485             {
1486                 "perfdata": [],
1487                 "status": {
1488                     "icingaapplication": {
1489                         "app": {
1490                             "enable_event_handlers": true,
1491                             "enable_flapping": true,
1492                             "enable_host_checks": true,
1493                             "enable_notifications": true,
1494                             "enable_perfdata": true,
1495                             "enable_service_checks": true,
1496                             "node_name": "example.localdomain",
1497                             "pid": 59819.0,
1498                             "program_start": 1443019345.093372,
1499                             "version": "v2.3.0-573-g380a131"
1500                         }
1501                     }
1502                 }
1503             }
1504         ]
1505     }
1506
1507
1508 ## Configuration Management <a id="icinga2-api-config-management"></a>
1509
1510 The main idea behind configuration management is to allow external applications
1511 creating configuration packages and stages based on configuration files and
1512 directory trees. This replaces any additional SSH connection and whatnot to
1513 dump configuration files to Icinga 2 directly.
1514 In case you are pushing a new configuration stage to a package, Icinga 2 will
1515 validate the configuration asynchronously and populate a status log which
1516 can be fetched in a separated request.
1517
1518
1519 ### Creating a Config Package <a id="icinga2-api-config-management-create-package"></a>
1520
1521 Send a `POST` request to a new config package called `example-cmdb` in this example. This
1522 will create a new empty configuration package.
1523
1524     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST \
1525     'https://localhost:5665/v1/config/packages/example-cmdb?pretty=1'
1526     {
1527         "results": [
1528             {
1529                 "code": 200.0,
1530                 "package": "example-cmdb",
1531                 "status": "Created package."
1532             }
1533         ]
1534     }
1535
1536 Package names starting with an underscore are reserved for internal packages and must not be used.
1537
1538 ### Uploading configuration for a Config Package <a id="icinga2-api-config-management-create-config-stage"></a>
1539
1540 Configuration files in packages are managed in stages.
1541 Stages provide a way to maintain multiple configuration versions for a package.
1542
1543 Send a `POST` request to the URL endpoint `/v1/config/stages` and add the name of an existing
1544 configuration package to the URL path (e.g. `example-cmdb`).
1545 The request body must contain the `files` attribute with the value being
1546 a dictionary of file targets and their content. You can also specify an optional `reload` attribute
1547 that will tell icinga2 to reload after stage config validation. By default this is set to `true`.
1548
1549 The file path requires one of these two directories inside its path:
1550
1551   Directory   | Description
1552   ------------|------------------------------------
1553   conf.d      | Local configuration directory.
1554   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).
1555
1556 Example for a local configuration in the `conf.d` directory:
1557
1558     "files": { "conf.d/host1.conf": "object Host \"local-host\" { address = \"127.0.0.1\", check_command = \"hostalive\" }" }
1559
1560 Example for a host configuration inside the `satellite` zone in the `zones.d` directory:
1561
1562     "files": { "zones.d/satellite/host2.conf": "object Host \"satellite-host\" { address = \"192.168.1.100\", check_command = \"hostalive\" }" }
1563
1564
1565 The example below will create a new file called `test.conf` in the `conf.d`
1566 directory. Note: This example contains an error (`chec_command`). This is
1567 intentional.
1568
1569     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST \
1570     -d '{ "files": { "conf.d/test.conf": "object Host \"cmdb-host\" { chec_command = \"dummy\" }" }, "pretty": true }' \
1571     'https://localhost:5665/v1/config/stages/example-cmdb'
1572     {
1573         "results": [
1574             {
1575                 "code": 200.0,
1576                 "package": "example-cmdb",
1577                 "stage": "example.localdomain-1441625839-0",
1578                 "status": "Created stage. Icinga2 will reload."
1579             }
1580         ]
1581     }
1582
1583 The Icinga 2 API returns the `package` name this stage was created for, and also
1584 generates a unique name for the `stage` attribute you'll need for later requests.
1585
1586 Icinga 2 automatically restarts the daemon in order to activate the new config stage. This
1587 can be disabled by setting `reload` to `false` in the request.
1588 If the validation for the new config stage failed, the old stage
1589 and its configuration objects will remain active.
1590
1591 > **Note**
1592 >
1593 > 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.
1594
1595 Icinga 2 will create the following files in the configuration package
1596 stage after configuration validation:
1597
1598   File        | Description
1599   ------------|--------------
1600   status      | Contains the [configuration validation](11-cli-commands.md#config-validation) exit code (everything else than 0 indicates an error).
1601   startup.log | Contains the [configuration validation](11-cli-commands.md#config-validation) output.
1602
1603 You can [fetch these files](12-icinga2-api.md#icinga2-api-config-management-fetch-config-package-stage-files)
1604 in order to verify that the new configuration was deployed successfully.
1605
1606
1607 ### List Configuration Packages and their Stages <a id="icinga2-api-config-management-list-config-packages"></a>
1608
1609 A list of packages and their stages can be retrieved by sending a `GET` request to the URL endpoint `/v1/config/packages`.
1610
1611 The following example contains one configuration package `example-cmdb`. The package does not currently
1612 have an active stage.
1613
1614     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/config/packages?pretty=1'
1615     {
1616         "results": [
1617             {
1618                 "active-stage": "",
1619                 "name": "example-cmdb",
1620                 "stages": [
1621                     "example.localdomain-1441625839-0"
1622                 ]
1623             }
1624         ]
1625     }
1626
1627
1628 ### List Configuration Packages and their Stages <a id="icinga2-api-config-management-list-config-package-stage-files"></a>
1629
1630 In order to retrieve a list of files for a stage you can send a `GET` request to
1631 the URL endpoint `/v1/config/stages`. You need to include
1632 the package name (`example-cmdb`) and stage name (`example.localdomain-1441625839-0`) in the URL:
1633
1634     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/config/stages/example-cmdb/example.localdomain-1441625839-0?pretty=1'
1635     {
1636         "results": [
1637     ...
1638             {
1639                 "name": "startup.log",
1640                 "type": "file"
1641             },
1642             {
1643                 "name": "status",
1644                 "type": "file"
1645             },
1646             {
1647                 "name": "conf.d",
1648                 "type": "directory"
1649             },
1650             {
1651                 "name": "zones.d",
1652                 "type": "directory"
1653             },
1654             {
1655                 "name": "conf.d/test.conf",
1656                 "type": "file"
1657             }
1658         ]
1659     }
1660
1661 ### Fetch Configuration Package Stage Files <a id="icinga2-api-config-management-fetch-config-package-stage-files"></a>
1662
1663 Send a `GET` request to the URL endpoint `/v1/config/files` and add
1664 the package name, the stage name and the relative path to the file to the URL path.
1665
1666 > **Note**
1667 >
1668 > The returned files are plain-text instead of JSON-encoded.
1669
1670 The following example fetches the configuration file `conf.d/test.conf`:
1671
1672     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/config/files/example-cmdb/example.localdomain-1441625839-0/conf.d/test.conf'
1673
1674     object Host "cmdb-host" { chec_command = "dummy" }
1675
1676 You can fetch a [list of existing files](12-icinga2-api.md#icinga2-api-config-management-list-config-package-stage-files)
1677 in a configuration stage and then specifically request their content.
1678
1679 ### Configuration Package Stage Errors <a id="icinga2-api-config-management-config-package-stage-errors"></a>
1680
1681 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),
1682 there must have been an error.
1683
1684 In order to check for validation errors you can fetch the `startup.log` file
1685 by sending a `GET` request to the URL endpoint `/v1/config/files`. You must include
1686 the package name, stage name and the `startup.log` in the URL path.
1687
1688     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/config/files/example-cmdb/example.localdomain-1441133065-1/startup.log'
1689     ...
1690
1691     critical/config: Error: Attribute 'chec_command' does not exist.
1692     Location:
1693     /var/lib/icinga2/api/packages/example-cmdb/example.localdomain-1441133065-1/conf.d/test.conf(1): object Host "cmdb-host" { chec_command = "dummy" }
1694                                                                                                            ^^^^^^^^^^^^^^^^^^^^^^
1695
1696     critical/config: 1 error
1697
1698 The output is similar to the manual [configuration validation](11-cli-commands.md#config-validation).
1699
1700 > **Note**
1701 >
1702 > The returned output is plain-text instead of JSON-encoded.
1703
1704
1705 ### Deleting Configuration Package Stage <a id="icinga2-api-config-management-delete-config-stage"></a>
1706
1707 You can send a `DELETE` request to the URL endpoint `/v1/config/stages`
1708 in order to purge a configuration stage. You must include the package and
1709 stage name inside the URL path.
1710
1711 The following example removes the failed configuration stage `example.localdomain-1441133065-1`
1712 in the `example-cmdb` configuration package:
1713
1714     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X DELETE \
1715     'https://localhost:5665/v1/config/stages/example-cmdb/example.localdomain-1441133065-1?pretty=1'
1716     {
1717         "results": [
1718             {
1719                 "code": 200.0,
1720                 "status": "Stage deleted."
1721             }
1722         ]
1723     }
1724
1725
1726 ### Deleting Configuration Package <a id="icinga2-api-config-management-delete-config-package"></a>
1727
1728 In order to completely purge a configuration package and its stages
1729 you can send a `DELETE` request to the URL endpoint `/v1/config/packages`
1730 with the package name in the URL path.
1731
1732 This example entirely deletes the configuration package `example-cmdb`:
1733
1734     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X DELETE \
1735     'https://localhost:5665/v1/config/packages/example-cmdb?pretty=1'
1736     {
1737         "results": [
1738             {
1739                 "code": 200.0,
1740                 "package": "example-cmdb",
1741                 "status": "Deleted package."
1742             }
1743         ]
1744     }
1745
1746
1747 ## Types <a id="icinga2-api-types"></a>
1748
1749 You can retrieve the configuration object types by sending a `GET` request to URL
1750 endpoint `/v1/types`.
1751
1752 Each response entry in the results array contains the following attributes:
1753
1754   Attribute       | Type         | Description
1755   ----------------|--------------|---------------------
1756   name            | String       | The type name.
1757   plural\_name    | String       | The plural type name.
1758   fields          | Dictionary   | Available fields including details on e.g. the type and attribute accessibility.
1759   abstract        | Boolean      | Whether objects can be instantiated for this type.
1760   base            | Boolean      | The base type (e.g. `Service` inherits fields and prototype methods from `Checkable`).
1761   prototype\_keys | Array        | Available prototype methods.
1762
1763 In order to view a specific configuration object type specify its name inside the URL path:
1764
1765     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/types/Object?pretty=1'
1766     {
1767         "results": [
1768             {
1769                 "abstract": false,
1770                 "fields": {
1771                     "type": {
1772                         "array_rank": 0.0,
1773                         "attributes": {
1774                             "config": false,
1775                             "navigation": false,
1776                             "no_user_modify": false,
1777                             "no_user_view": false,
1778                             "required": false,
1779                             "state": false
1780                         },
1781                         "id": 0.0,
1782                         "type": "String"
1783                     }
1784                 },
1785                 "name": "Object",
1786                 "plural_name": "Objects",
1787                 "prototype_keys": [
1788                     "clone",
1789                     "notify_attribute",
1790                     "to_string"
1791                 ]
1792             }
1793         ]
1794     }
1795
1796
1797 ## Console <a id="icinga2-api-console"></a>
1798
1799 You can inspect variables and execute other expressions by sending a `POST` request to the URL endpoint `/v1/console/execute-script`.
1800 In order to receive auto-completion suggestions, send a `POST` request to the URL endpoint `/v1/console/auto-complete-script`.
1801
1802 The following parameters need to be specified (either as URL parameters or in a JSON-encoded message body):
1803
1804   Parameter  | Type         | Description
1805   -----------|--------------|-------------
1806   session    | String       | **Optional.** The session ID. Ideally this should be a GUID or some other unique identifier.
1807   command    | String       | **Required.** Command expression for execution or auto-completion.
1808   sandboxed  | Number       | **Optional.** Whether runtime changes are allowed or forbidden. Defaults to disabled.
1809
1810 The [API permission](12-icinga2-api.md#icinga2-api-permissions) `console` is required for executing
1811 expressions.
1812
1813 > **Note**
1814 >
1815 > Runtime modifications via `execute-script` calls are not validated and might cause the Icinga 2
1816 > daemon to crash or behave in an unexpected way. Use these runtime changes at your own risk.
1817
1818 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).
1819
1820 Example for fetching the command line from the local host's last check result:
1821
1822     $ curl -k -s -u root:icinga -H 'Accept: application/json' -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'
1823     {
1824         "results": [
1825             {
1826                 "code": 200.0,
1827                 "result": [
1828                     "/usr/local/sbin/check_ping",
1829                     "-H",
1830                     "127.0.0.1",
1831                     "-c",
1832                     "5000,100%",
1833                     "-w",
1834                     "3000,80%"
1835                 ],
1836                 "status": "Executed successfully."
1837             }
1838         ]
1839     }
1840
1841 Example for fetching auto-completion suggestions for the `Host.` type. This works in a
1842 similar fashion when pressing TAB inside the [console CLI command](11-cli-commands.md#cli-command-console):
1843
1844     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/console/auto-complete-script?command=Host.&sandboxed=0&session=bb75fd7c-c686-407d-9688-582c04227756&pretty=1'
1845     {
1846         "results": [
1847             {
1848                 "code": 200.0,
1849                 "status": "Auto-completed successfully.",
1850                 "suggestions": [
1851                     "Host.type",
1852                     "Host.name",
1853                     "Host.prototype",
1854                     "Host.base",
1855                     "Host.register_attribute_handler",
1856                     "Host.clone",
1857                     "Host.notify_attribute",
1858                     "Host.to_string"
1859                 ]
1860             }
1861         ]
1862     }
1863
1864
1865 ## API Clients <a id="icinga2-api-clients"></a>
1866
1867 There are a couple of existing clients which can be used with the Icinga 2 API:
1868
1869 * [curl](https://curl.haxx.se/) or any other HTTP client really
1870 * [Icinga 2 console (CLI command)](12-icinga2-api.md#icinga2-api-clients-cli-console)
1871 * [Icinga Web 2 Director](https://www.icinga.com/products/icinga-web-2-modules/)
1872
1873 Demo cases:
1874
1875 * [Dashing](https://github.com/Icinga/dashing-icinga2)
1876 * [API examples](https://github.com/Icinga/icinga2-api-examples)
1877
1878 Additional [programmatic examples](12-icinga2-api.md#icinga2-api-clients-programmatic-examples)
1879 will help you getting started using the Icinga 2 API in your environment.
1880
1881 ### Icinga 2 Console <a id="icinga2-api-clients-cli-console"></a>
1882
1883 By default the [console CLI command](11-cli-commands.md#cli-command-console) evaluates
1884 expressions in a local interpreter, i.e. independently from your Icinga 2 daemon.
1885 Add the `--connect` parameter to debug and evaluate expressions via the API.
1886
1887 ### API Clients Programmatic Examples <a id="icinga2-api-clients-programmatic-examples"></a>
1888
1889 The programmatic examples use HTTP basic authentication and SSL certificate
1890 verification. The CA file is expected in `pki/icinga2-ca.crt`
1891 but you may adjust the examples for your likings.
1892
1893 The [request method](icinga2-api-requests) is `POST` using
1894 [X-HTTP-Method-Override: GET](12-icinga2-api.md#icinga2-api-requests-method-override)
1895 which allows you to send a JSON request body. The examples request
1896 specific service attributes joined with host attributes. `attrs`
1897 and `joins` are therefore specified as array.
1898 The `filter` attribute [matches](18-library-reference.md#global-functions-match)
1899 on all services with `ping` in their name.
1900
1901 #### Example API Client in Python <a id="icinga2-api-clients-programmatic-examples-python"></a>
1902
1903 The following example uses **Python** and the `requests` and `json` module:
1904
1905     # pip install requests
1906     # pip install json
1907
1908     $ vim icinga2-api-example.py
1909
1910     #!/usr/bin/env python
1911     
1912     import requests, json
1913     
1914     # Replace 'localhost' with your FQDN and certificate CN
1915     # for SSL verification
1916     request_url = "https://localhost:5665/v1/objects/services"
1917     headers = {
1918             'Accept': 'application/json',
1919             'X-HTTP-Method-Override': 'GET'
1920             }
1921     data = {
1922             "attrs": [ "name", "state", "last_check_result" ],
1923             "joins": [ "host.name", "host.state", "host.last_check_result" ],
1924             "filter": "match(\"ping*\", service.name)",
1925     }
1926     
1927     r = requests.post(request_url,
1928             headers=headers,
1929             auth=('root', 'icinga'),
1930             data=json.dumps(data),
1931             verify="pki/icinga2-ca.crt")
1932     
1933     print "Request URL: " + str(r.url)
1934     print "Status code: " + str(r.status_code)
1935     
1936     if (r.status_code == 200):
1937             print "Result: " + json.dumps(r.json())
1938     else:
1939             print r.text
1940             r.raise_for_status()
1941
1942     $ python icinga2-api-example.py
1943
1944
1945 #### Example API Client in Ruby <a id="icinga2-api-clients-programmatic-examples-ruby"></a>
1946
1947 The following example uses **Ruby** and the `rest_client` gem:
1948
1949     # gem install rest_client
1950
1951     $ vim icinga2-api-example.rb
1952
1953     #!/usr/bin/ruby
1954     
1955     require 'rest_client'
1956     
1957     # Replace 'localhost' with your FQDN and certificate CN
1958     # for SSL verification
1959     request_url = "https://localhost:5665/v1/objects/services"
1960     headers = {
1961             "Accept" => "application/json",
1962             "X-HTTP-Method-Override" => "GET"
1963     }
1964     data = {
1965             "attrs" => [ "name", "state", "last_check_result" ],
1966             "joins" => [ "host.name", "host.state", "host.last_check_result" ],
1967             "filter" => "match(\"ping*\", service.name)",
1968     }
1969     
1970     r = RestClient::Resource.new(
1971             URI.encode(request_url),
1972             :headers => headers,
1973             :user => "root",
1974             :password => "icinga",
1975             :ssl_ca_file => "pki/icinga2-ca.crt")
1976     
1977     begin
1978             response = r.post(data.to_json)
1979     rescue => e
1980             response = e.response
1981     end
1982     
1983     puts "Status: " + response.code.to_s
1984     if response.code == 200
1985             puts "Result: " + (JSON.pretty_generate JSON.parse(response.body))
1986     else
1987             puts "Error: " + response
1988     end
1989
1990     $ ruby icinga2-api-example.rb
1991
1992 A more detailed example can be found in the [Dashing demo](https://github.com/Icinga/dashing-icinga2).
1993
1994 #### Example API Client in PHP <a id="icinga2-api-clients-programmatic-examples-php"></a>
1995
1996 The following example uses **PHP** and its `curl` library:
1997
1998     $ vim icinga2-api-example.php
1999
2000     #!/usr/bin/env php
2001     <?php
2002     # Replace 'localhost' with your FQDN and certificate CN
2003     # for SSL verification
2004     $request_url = "https://localhost:5665/v1/objects/services";
2005     $username = "root";
2006     $password = "icinga";
2007     $headers = array(
2008             'Accept: application/json',
2009             'X-HTTP-Method-Override: GET'
2010     );
2011     $data = array(
2012             attrs => array('name', 'state', 'last_check_result'),
2013             joins => array('host.name', 'host.state', 'host.last_check_result'),
2014             filter => 'match("ping*", service.name)',
2015     );
2016     
2017     $ch = curl_init();
2018     curl_setopt_array($ch, array(
2019             CURLOPT_URL => $request_url,
2020             CURLOPT_HTTPHEADER => $headers,
2021             CURLOPT_USERPWD => $username . ":" . $password,
2022             CURLOPT_RETURNTRANSFER => true,
2023             CURLOPT_CAINFO => "pki/icinga2-ca.crt",
2024             CURLOPT_POST => count($data),
2025             CURLOPT_POSTFIELDS => json_encode($data)
2026     ));
2027     
2028     $response = curl_exec($ch);
2029     if ($response === false) {
2030             print "Error: " . curl_error($ch) . "(" . $response . ")\n";
2031     }
2032     
2033     $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
2034     curl_close($ch);
2035     print "Status: " . $code . "\n";
2036     
2037     if ($code == 200) {
2038             $response = json_decode($response, true);
2039             print_r($response);
2040     }
2041     ?>
2042
2043     $ php icinga2-api-example.php
2044
2045 #### Example API Client in Perl <a id="icinga2-api-clients-programmatic-examples-perl"></a>
2046
2047 The following example uses **Perl** and the `Rest::Client` module:
2048
2049     # perl -MCPAN -e 'install REST::Client'
2050     # perl -MCPAN -e 'install JSON'
2051     # perl -MCPAN -e 'install MIME::Base64'
2052     # perl -MCPAN -e 'install Data::Dumper'
2053
2054     $ vim icinga2-api-example.pl
2055
2056     #!/usr/bin/env perl
2057     
2058     use strict;
2059     use warnings;
2060     use REST::Client;
2061     use MIME::Base64;
2062     use JSON;
2063     use Data::Dumper;
2064     
2065     # Replace 'localhost' with your FQDN and certificate CN
2066     # for SSL verification
2067     my $request_host = "https://localhost:5665";
2068     my $userpass = "root:icinga";
2069     
2070     my $client = REST::Client->new();
2071     $client->setHost($request_host);
2072     $client->setCa("pki/icinga2-ca.crt");
2073     $client->addHeader("Accept", "application/json");
2074     $client->addHeader("X-HTTP-Method-Override", "GET");
2075     $client->addHeader("Authorization", "Basic " . encode_base64($userpass));
2076     my %json_data = (
2077             attrs => ['name', 'state', 'last_check_result'],
2078             joins => ['host.name', 'host.state', 'host.last_check_result'],
2079             filter => 'match("ping*", service.name)',
2080     );
2081     my $data = encode_json(\%json_data);
2082     $client->POST("/v1/objects/services", $data);
2083     
2084     my $status = $client->responseCode();
2085     print "Status: " . $status . "\n";
2086     my $response = $client->responseContent();
2087     if ($status == 200) {
2088             print "Result: " . Dumper(decode_json($response)) . "\n";
2089     } else {
2090             print "Error: " . $response . "\n";
2091     }
2092
2093     $ perl icinga2-api-example.pl
2094