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:

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,
           "active": 1,
           "id": 123456,
           "name": "foo-sla0"
       }
   ]
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
            }
        ]
    ],
    "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
            }
        ]
    ],
    "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.

Request Headers:
 

/v0/incidents

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 655355 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”.

Request Headers:
 
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
}

/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.

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"
}

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
  • both priority and mode are missing
  • invalid priority, mode
  • both tempalte, body and email_html are missing
  • template, body and email_html is not a string
  • message queue request rejected by sender
Request Headers:
 

/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/users

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:
 

/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:
 

/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:
 
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"
    }
]

/healthcheck

GET /healthcheck

Healthcheck endpoint. Returns contents of healthcheck file.

Example request:

GET /v0/healthcheck HTTP/1.1

Example response:

HTTP/1.1 200 OK
Content-Type: text/plain

GOOD