REST API¶
HMAC Auth¶
API requests which require API key auth will have an extra
AUTHORIZATION
HTTP header. It looks like this:
AUTHORIZATION: hmac $application:$payload
$payload
is a base64 encoded hmac sha512 digest of the following string
with the app’s API key. In the resulting base64 string, instances of +
are replaced with -
and /
are replaced with _
.
HMAC($api_key, "$window $httpMethod $path $body")
$window
is the current unix timestamp in seconds, divided by 5, floor’d.
$httpMethod
is generally POST
$path
is the path portion of the URL, such as /v0/incidents
$body
is generally the json-formatted post body.
Example client implementations:
Query Filters¶
Iris has a number of search endpoints allowing filtering based on data
attributes. For each allowable attribute, filters are defined via the
query string, with syntax in the form of
$ATTRIBUTE__$OPERATOR=$ARGUMENT
e.g. created__ge=123
.
The following operators are allowed:
“eq”:
$ATTRIBUTE == $ARGUMENT
“in”:
$ATTRIBUTE
is contained in$ARGUMENT
, which must be a list“ne”:
$ATTRIBUTE != $ARGUMENT
“gt”:
$ATTRIBUTE > $ARGUMENT
“ge”:
$ATTRIBUTE >= $ARGUMENT
“lt”:
$ATTRIBUTE < $ARGUMENT
“le”:
$ATTRIBUTE <= $ARGUMENT
“contains”:
$ATTRIBUTE
contains the substring$ARGUMENT
. Only defined on string-like attributes“startswith”:
$ATTRIBUTE
starts with$ARGUMENT
. Only defined on string-like attributes“endswith”:
$ATTRIBUTE
ends with$ARGUMENT
. Only defined on string-like attributes
If no operator is defined (e.g. id=123
), the operator
is assumed to be “eq” (equality).
Routes¶
/v0/plans¶
- GET /v0/plans¶
Plan search endpoint.
Example request:
GET /v0/plans?name__contains=foo&active=1 HTTP/1.1 **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json [ { "description": "This is plan foo", "threshold_count": 10, "creator": "user1", "created": 1478154275, "aggregation_reset": 300, "aggregation_window": 300, "threshold_window": 900, "tracking_type": null, "tracking_template": null, "tracking_key": null, "dynamic_tracking": 1, "active": 1, "id": 123456, "name": "foo-sla0" } ]
You can also search for plans that have specific targets in their steps by using the field ‘target’
Allowed filter parameters:
id
name
tracking_type
tracking_key
created
creator
active
tags
for querying tags a “tag_” prefix should be added before the tag name and then it can be used just as any other normal field e.g. if we want to query for a plan that has a tag “service” with a value “foo” we would query: /v0/plan?tag_service=foo
example request
GET /v0/plans?target=foo&active=1 HTTP/1.1
Additionally adding the parameter “counts” will return a dictionary with unique values of each field and their counts as well as a total count
Example request:
GET /v0/plans?counts=true&fields=creator HTTP/1.1 Host: example.com
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "field_counts": { "creator": { "user_foo": 10, "user_bar": 20, "user_baz": 5 } }, "total_count": 35 }
- POST /v0/plans¶
Plan create endpoint. Plans can either be static, defining role/targets in plan creation, or dynamic, leaving these fields blank during creation and determining role/targets at incident creation time. Static plan example:
Example request:
POST /v0/plans HTTP/1.1 { "aggregation_reset": 300, "aggregation_window": 300, "creator": "user-foo", "description": "this is a plan", "name": "plan-foo", "steps": [ [ { "priority": "urgent", "repeat": 0, "role": "user", "target": "demo", "template": "template-foo", "wait": 0 "optional": 0 } ] ], "threshold_count": 10, "threshold_window": 900 }
Example response:
HTTP/1.1 201 Created Content-Type: application/json 1
Aggregation: If a user receives more than $threshold_count messages from this plan via a given medium within $threshold_window seconds, group their messages for $aggregation_window seconds. After $aggregation_reset seconds without a message, aggregation stops.
For a static plan, “steps” should be a list of arrays of JSON objects defining “priority”, “repeat”, “role”, “target”, “template”, and “wait”. Each array of objects represents a step in the plan, with the JSON objects representing the notifications delivered in that step. These notifications occur in parallel with one another within a given step. Descriptions of these parameters:
- priority
Priority of messages sent by this step sub-part
- repeat
Number of times this message will be repeated (e.g. repeat == 0 => 1 message)
- role
Role of the target
- target
Name of the target
- template
Name of the template user to format this message
- wait
Time to wait until sending a repeat message or moving on to the next plan step.
Dynamic plan example:
Example request:
POST /v0/plans HTTP/1.1 { "aggregation_reset": 300, "aggregation_window": 300, "creator": "user-foo", "description": "this is a plan", "isValid": true, "name": "plan-foo", "steps": [ [ { "dynamic_index": 0, "priority": "urgent", "repeat": 0, "template": "template-foo", "wait": 0 "optional": 0 } ] ], "threshold_count": 10, "threshold_window": 900 }
Example response:
HTTP/1.1 201 Created Content-Type: application/json 1
For dynamic plans, step sub-parts define a “dynamic index” rather than a role/target combination. These indices must span a range from 0..n, where n is the largest dynamic index provided. At incident creation time, a mapping of dynamic index to role/target is provided to define the recipient of a message. See incidents POST endpoint for details.
The total time of all plan steps can not exceed 24 hours.
- Request Headers
Authorization – see HMAC Auth.
/v0/incidents¶
- GET /v0/incidents¶
Search for incidents. Returns a list of incidents matching specified parameters. Valid parameters are listed below:
Example request:
GET /v0/incidents?owner=jdoe&created__gt=1487466146&fields=id,owner HTTP/1.1 Host: example.com
Example response:
HTTP/1.1 200 OK Content-Type: application/json [ { "id": 123, "owner": "jdoe" }, { "id": 124, "owner": "jdoe" } ]
- Status Codes
400 Bad Request – Too much data requested; more filters are required
200 OK – Successful query
Allowed filter parameters:
id: Incident id (int)
created: Incident creation time, in seconds since Unix epoch (int)
owner: Username of person who claimed the incident (string)
updated: Time when incident was last updated (e.g. claimed), in seconds since epoch (int)
active: Incident status. Incidents are active if unclaimed, and inactive if they are claimed or finished with their escalation plan (0 or 1 for inactive/active, respectively)
context: JSON string representing the incident context data
application: Application that created this incident (string)
plan: Escalation plan name (string)
plan_id: Escalation plan id (int)
claimed: Claimed status (bool)
tags: Arbitrary metadata tags associated with the incident
This endpoint also allows specification of a limit via another query parameter, which limits results to the N most recent incidents. Calls to this endpoint that do not specify either a limit or a filter will be rejected. To specify which incident attribute should be included in the output, the “fields” query parameter can be used. The fields parameter takes the value of a comma-separated list of attributes (e.g. id,owner), and the API will only include these incident fields in the output. If no “fields” value is specified, all fields will be returned.
for querying tags a “tag_” prefix should be added before the tag name and then it can be used just as any other normal field e.g. if we want to query for an incident that has a tag “service” with a value “foo” we would query: /v0/incidents?tag_service=foo
Additionally adding the parameter “counts” will return a dictionary with unique values of each field and their counts as well as a total count
Sorting by specific fields. You can use the parameter order_by eg. order_by=$FIELD to sort the response by a specific field. Supported fields are: - id - created - updated - owner - application - plan - context - active
Specify the order of the sort with the order parameter eg order=ASC. Supported values are: - ASC - DESC
Example request:
GET /v0/incidents?created__ge=1700693640&fields=owner&fields=application&counts=true HTTP/1.1 Host: example.com
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "field_counts": { "owner": { "foo_user": 4, "None": 7 }, "application": { "Autoalerts": 11 } }, "total_count": 11 }
- POST /v0/incidents¶
Create incidents. Id for the new incident will be returned.
Example request:
POST /v0/incidents HTTP/1.1 Content-Type: application/json { "plan": "test-plan", "context": {"number": 1, "str": "hello"} }
Example response:
HTTP/1.1 201 Created Content-Type: application/json 1
- statuscode 201
incident created
- statuscode 400
invalid request
- statuscode 404
plan not found
- statuscode 401
application is not allowed to create incident for other application
A request is considered invalid if:
plan name is missing
application is invalid
context json blob is longer than 65535 bytes
none of the templates used in the plan supports the given application
To create an incident for a dynamic plan (one that defines dynamic targets), an additional dynamic_targets field must be passed along with the plan and context. Consider a dynamic plan defining two dynamic targets, indexed with 0 and 1. The dynamic_targets parameter should take the following form:
[ { "role": "user", "target": "jdoe" }, { "role": "team", "target": "team-foo" } ]
This will map target 0 to the user “jdoe”, and target 1 to the team “team-foo”.
To use dynamic tracking you can pass a dynamic_tracking_notifications list in the incident_params. If the plan has dynamic tracking enabled, the incident will be created with the dynamic tracking notifications specified in the incident_params. The tracking message will use the tracking template specified in the plan.
“dynamic_tracking_notifications”: [{“mode”: “slack”, “destination”: “#iris-slack-testing”}, {“mode”: “slack”, “destination”: “#iris-slack-testing2”}]
- Request Headers
Authorization – see HMAC Auth.
- GET /v0/incidents/{incident_id}¶
Get incident by ID.
Example request:
GET /v0/incident/1 HTTP/1.1
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "updated": 1492057026, "plan_id": 48271, "created": 1492055912, "application": "Alert manager", "steps": [ { "name": "alice", "created": 1492055953, "target_changed": 0, "mode_changed": 0, "priority": "urgent", "step": 1, "mode": "sms", "id": 25443689, "sent": 1492055957 } ], "plan": "test-plan", "context": {"number": 1, "str": "hello"}, "owner": "alice", "active": 0, "id": 1, "current_step": 1 }
- POST /v0/incidents/{incident_id}¶
Claim incidents by incident id. Deactivates the incident and any associated messages, preventing further escalation.
Example request:
POST /v0/incidents/123 HTTP/1.1 Content-Type: application/json { "owner": "jdoe" }
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "incident_id": "123", "owner": "jdoe", "active": false }
- Request Headers
Authorization – see HMAC Auth.
/v0/messages¶
- GET /v0/messages/{message_id}¶
Get information for an iris message by id
Example request:
GET /v0/messages/{message_id} HTTP/1.1
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "body": "message body", "incident_id": 2590447, "target": "username", "created": 1490825218, "destination": "username@domain.com", "batch": null, "twilio_delivery_status": null, "priority": "low", "application": "app", "mode": "email", "active": 0, "generic_message_sent_status": 1, "id": 24807074, "sent": 1490825221, "subject": "message subject" }
- GET /v0/messages/{message_id}/auditlog¶
Get a message’s log of changes
Example request:
GET /v0/messages/{message_id}/auditlog HTTP/1.1
Example response:
HTTP/1.1 200 OK Content-Type: application/json [ { "old": "sms", "description": "Changing mode due to original mode failure", "date": 1489507284, "new": "email", "change_type": "mode-change", "id": 438 }, ]
/v0/notifications¶
- POST /v0/notifications¶
Create out of band notifications. Notification is ad-hoc message that’s not tied to an incident. To achieve real-time delivery, notifications are not persisted in the Database.
You can set the priority key to honor target’s priority preference or set the mode key to force the message transport.
You can use the role “literal_target” to prevent unrolling of targets and send messages directly to mailing lists or slack channels. Note that if you use this role you MUST specify the mode key but not the priority. This role will set the destination to the target value so make sure the target is a valid email address, slack channel, slack username, etc.
Multi-recipient messages are supported for notifications explicitly specifying the “email” mode. To send a multi-recipient message, specify a list of objects defining “role” and “target” attributes. All roles, including “literal_target”, are supported. These messages will be sent on a best-effort basis to as many targets as is possible. If any role:target pairs are found to be invalid, they will be skipped, and the message will be delivered to all other targets. Each object can also optionally define a “bcc” field, which will mark those targets as bcc if set to true. If no bcc attribute is defined for a target, the default value is false.
Example request:
POST /v0/notifications HTTP/1.1 Content-Type: application/json { "role": "secondary-oncall", "target": "test_oncall_team", "subject": "wake up", "body": "something is on fire", "priority": "high" }
POST /v0/notifications HTTP/1.1 Content-Type: application/json { "role": "user", "target": "test_user", "subject": "wake up", "body": "something is on fire", "mode": "email" }
POST /v0/notifications HTTP/1.1 Content-Type: application/json { "role": "literal_target", "target": "#slackchannel", "subject": "wake up", "body": "something is on fire", "mode": "slack" }
POST /v0/notifications HTTP/1.1 Content-Type: application/json { "target_list": { { "role": "literal_target", "target": "list@example.com" }, { "role": "user", "target": "jdoe", "bcc": true } } "subject": "wake up", "body": "something is on fire", "mode": "email" }
Example response:
HTTP/1.1 200 OK Content-Type: application/json []
- statuscode 200
notification send request queued
- statuscode 400
invalid request
- statuscode 401
application is not allowed to create out of band notification
A request is considered invalid if:
either target, subject or role is missing and target_list is not provided
target_list is provided, but no subject
target_list is malformed (not of the form [{“role”: foo, “target”: bar}])
a priority is given for a target_list
both priority and mode are missing
invalid priority, mode
both template, body and email_html are missing
template, body and email_html is not a string
message queue request rejected by sender
- Request Headers
Authorization – see HMAC Auth.
/v0/target_roles¶
- GET /v0/target_roles¶
Target role fetch endpoint.
Example request:
GET /v0/target_roles HTTP/1.1
Example response:
HTTP/1.1 200 OK Content-Type: application/json [ { "name": "user", "type": "user" }, { "name": "oncall", "type": "team" } ]
/v0/templates¶
- GET /v0/templates/{template_id}¶
Template search endpoint.
Example request:
GET /v0/templates?name__contains=foo&active=1 HTTP/1.1 **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json [ { "id": 5050, "name": "test_template", "creator": "foo_user", "created": 1698419737, "active": 1, "tags": [] }, { "id": 5034, "name": "test_template_also", "creator": "foo_user", "created": 1657829790, "active": 1, "tags": [] } ]
Allowed filter parameters:
id
name
created
creator
active
tags
for querying tags a “tag_” prefix should be added before the tag name and then it can be used just as any other normal field e.g. if we want to query for a template that has a tag “service” with a value “foo” we would query: /v0/templates?tag_service=foo
Additionally adding the parameter “counts” will return a dictionary with unique values of each field and their counts as well as a total count
Example request:
GET /v0/templates?counts=true&fields=creator HTTP/1.1 Host: example.com
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "field_counts": { "creator": { "user_foo": 10, "user_bar": 20, "user_baz": 5 } }, "total_count": 35 }
/v0/users¶
- DELETE /v0/users/{username}/categories¶
Delete a user’s category settings for a given app, removing all overrides for that app. Essentially sets all categories back to default.
Example request:
DELETE /v0/users/jdoe/categories/foo-app HTTP/1.1
Example response:
HTTP/1.1 204 No Content Content-Type: application/json
- Request Headers
Authorization – see HMAC Auth.
- GET /v0/users/{username}/categories¶
Get notification category overrides by user. Returns a list of override objects, defining the app, category, and override mode. If no application is provided in the URL, returns all category overrides for the user.
Example request:
GET /v0/users/jdoe/categories/foo-app HTTP/1.1
Example response:
HTTP/1.1 200 OK Content-Type: application/json [ { "application": "foo-app", "category": "bar-category", "mode": "drop" } ]
- Request Headers
Authorization – see HMAC Auth.
- POST /v0/users/{username}/categories¶
Create and edit a user’s overrides for an application. Takes a mapping of category_name: mode. For each category passed, either creates or overwrites the user’s settings for that category, mapping it to the given mode. If the mode is null/None, instead deletes that mapping to revert the category setting to default. e.g. passing {“foo”: “email”, “bar”: None} will delete the setting for “bar” and map “foo” to “email”, regardless of whether “foo” previously had another setting.
Example request:
POST /v0/categories/123 HTTP/1.1 Content-Type: application/json { "foo-category": "drop", "bar-category": null, }
Example response:
HTTP/1.1 201 Created Content-Type: application/json
- Request Headers
Authorization – see HMAC Auth.
- DELETE /v0/users/{username}/categories/{application}¶
Delete a user’s category settings for a given app, removing all overrides for that app. Essentially sets all categories back to default.
Example request:
DELETE /v0/users/jdoe/categories/foo-app HTTP/1.1
Example response:
HTTP/1.1 204 No Content Content-Type: application/json
- Request Headers
Authorization – see HMAC Auth.
- GET /v0/users/{username}/categories/{application}¶
Get notification category overrides by user. Returns a list of override objects, defining the app, category, and override mode. If no application is provided in the URL, returns all category overrides for the user.
Example request:
GET /v0/users/jdoe/categories/foo-app HTTP/1.1
Example response:
HTTP/1.1 200 OK Content-Type: application/json [ { "application": "foo-app", "category": "bar-category", "mode": "drop" } ]
- Request Headers
Authorization – see HMAC Auth.
- POST /v0/users/{username}/categories/{application}¶
Create and edit a user’s overrides for an application. Takes a mapping of category_name: mode. For each category passed, either creates or overwrites the user’s settings for that category, mapping it to the given mode. If the mode is null/None, instead deletes that mapping to revert the category setting to default. e.g. passing {“foo”: “email”, “bar”: None} will delete the setting for “bar” and map “foo” to “email”, regardless of whether “foo” previously had another setting.
Example request:
POST /v0/categories/123 HTTP/1.1 Content-Type: application/json { "foo-category": "drop", "bar-category": null, }
Example response:
HTTP/1.1 201 Created Content-Type: application/json
- Request Headers
Authorization – see HMAC Auth.
- GET /v0/users/{username}/slackid¶
Retrieve the slack user ID that corresponds to an Iris username.
Example request:
GET /v0/users/jdoe/slackid HTTP/1.1
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "slack_id": "12345ABCD", }
- GET /v0/users/modes/{username}¶
Get priority:mode mappings for a given user. If no application is passed via query params, returns a user’s global priority:mode mapping. Otherwise, return the per-application priority mapping that corresponds to the specified application. Any undefined mapping has “default” specified as mode, otherwise the mode’s name is specified.
This action is only available if the request’s username matches the username passed in the URL. Admins and apps that can authenticate as users are also allowed to access this data.
Example request:
GET /v0/users/modes/jdoe?application=foo HTTP/1.1 Content-Type: application/json
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "high": "default", "low": "email", "medium": "slack", "urgent": "default", }
- Request Headers
Authorization – see HMAC Auth.
- POST /v0/users/modes/{username}¶
Update priority:mode mappings for a given user. To update global priority mappings, specify the priority and new value in the base level of the post body. For per application settings, define new values in a dict mapping to the app’s name under the “per_app_modes” key. To delete settings, specify “default” as the mode mapping. Any priority/app not specified in the request is unchanged.
This API responds with the new value of the global priority:mode mapping after the request has been made.
This action is available only to the user matching the username in the URL, to admins, and to apps that can authenticate as users.
Example request:
POST /v0/notifications HTTP/1.1 Content-Type: application/json { "urgent": "default", "high": "slack", "medium": "slack", "low": "default", "per_app_modes": { "foo-app": { "urgent": "default", "high": "default", "medium": "default", "low": "email" }, "bar-app": { "urgent": "default", "high": "default", "medium": "default", "low": "default" } } }
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "urgent": "default", "high": "slack", "medium": "slack", "low": "default", }
- Request Headers
Authorization – see HMAC Auth.
- DELETE /v0/users/reprioritization/{username}/{src_mode_name}¶
Delete a reprioritization mode for a user’s mode setting
Example request:
DELETE /v0/users/reprioritization/{username}/{src_mode_name} HTTP/1.1
Example response:
HTTP/1.1 200 OK Content-Type: application/json []
- Request Headers
Authorization – see HMAC Auth.
/v0/modes¶
- GET /v0/modes¶
List all iris modes
Example request:
GET /v0/modes HTTP/1.1
Example response:
HTTP/1.1 200 OK Content-Type: application/json ["sms", "email", "slack", "call"]
- Request Headers
Authorization – see HMAC Auth.
/v0/applications¶
- GET /v0/applications/{app_name}/incident_emails¶
Get email addresses which will create incidents on behalf of this application
Example request:
GET /v0/applications/{app_name}/incident_emails HTTP/1.1
Example response:
HTTP/1.1 200 OK Content-Type: application/json { "incident@fakeemail.cde": "page_oncall_plan", "audit@fakeemail.abc": "audit_plan" }
- Request Headers
Authorization – see HMAC Auth.
- GET /v0/applications/{app_name}/plans¶
Search endpoint for active plans that support a given app. A plan supports an app if one of its steps uses a template that defines content for that application.
Example request:
GET /v0/applications/app-foo/plans?name__contains=bar& HTTP/1.1
Example response:
HTTP/1.1 200 OK Content-Type: application/json [ { "description": "This is plan bar", "threshold_count": 10, "creator": "user1", "created": 1478154275, "aggregation_reset": 300, "aggregation_window": 300, "threshold_window": 900, "tracking_type": null, "tracking_template": null, "tracking_key": null, "active": 1, "id": 123456, "name": "bar-sla0" } ]
- GET /v0/applications/{app_name}/templates¶
Search endpoint for active templates that support a given app.
Example request:
GET /v0/applications/app-foo/templates?name__contains=bar& HTTP/1.1
Example response:
HTTP/1.1 200 OK Content-Type: application/json [ { "id": 3943, "name": "template-name-foo", "creator": "fooUser", "created": 1489604094, "active": 1, "tags": null }, { "id": 4928, "name": "template-name-bar", "creator": "BarUser", "created": 1585762825, "active": 1, "tags": null } ]
/v0/categories¶
- GET /v0/categories¶
Notification category search. Can filter based on id, name, app name, and mode. Returns a list of categories matching the specified filters.
Example request:
GET /v0/categories?name__startswith=foo&application=app HTTP/1.1
Example response:
HTTP/1.1 200 OK Content-Type: application/json [ { "id": 123, "name": "foobar", "application": "app", "mode": "email" } ]
- POST /v0/categories¶
Create notification categories for a given app. Pass a list of categories representing all notification categories for the app. This endpoint will create, edit, and delete the app’s categories to match the list passed in.
Example request:
POST /v0/categories/foo-app HTTP/1.1 Content-Type: application/json [ { "name": "foo-category", "description": "foobar", "mode": "email" }, { "name": "bar-category", "description": "barbaz", "mode": "slack" } ]
Example response:
HTTP/1.1 200 OK Content-Type: application/json
- statuscode 200
categories saved
- statuscode 400
invalid request, missing required attributes
- statuscode 401
user/app is not allowed to create categories for this app
- Request Headers
Authorization – see HMAC Auth.
- GET /v0/categories/{application}¶
Notification category search. Can filter based on id, name, app name, and mode. Returns a list of categories matching the specified filters.
Example request:
GET /v0/categories?name__startswith=foo&application=app HTTP/1.1
Example response:
HTTP/1.1 200 OK Content-Type: application/json [ { "id": 123, "name": "foobar", "application": "app", "mode": "email" } ]
- POST /v0/categories/{application}¶
Create notification categories for a given app. Pass a list of categories representing all notification categories for the app. This endpoint will create, edit, and delete the app’s categories to match the list passed in.
Example request:
POST /v0/categories/foo-app HTTP/1.1 Content-Type: application/json [ { "name": "foo-category", "description": "foobar", "mode": "email" }, { "name": "bar-category", "description": "barbaz", "mode": "slack" } ]
Example response:
HTTP/1.1 200 OK Content-Type: application/json
- statuscode 200
categories saved
- statuscode 400
invalid request, missing required attributes
- statuscode 401
user/app is not allowed to create categories for this app
- Request Headers
Authorization – see HMAC Auth.