User Guide: REST Interface

This document provides a brief introduction to requesting sleep predictions and recommendations, based on the Sydney-CRC Model of Sleep and Alertness, via the RESTish API at https://www.alertnessapi.com/v3.

If you have not already done so, you should start with the general user guide.

For a guide to submitting queries and retrieving results using your browser, see the browser interface guide.


Access Flow

Basic use involves accessing only three of the endpoints available at https://www.alertnessapi.com

  1. /v3/queryPOST a request for sleep predictions or recommendations;
  2. /v3/status/{query_id}GET the status of a specific request;
  3. /v3/result/{query_id}GET the results of your query (once status=COMPLETE).

Note: The /result endpoint for a query does not exist until the status for the query is COMPLETE.

Calculating a few days to a week worth of sleep and alertness predictions currently takes a few seconds to complete. Calculating a few days to a week worth of sleep recommendations currently takes between thirty seconds and a few minutes to complete.


Input

There is a formal definition of the structure of the input accepted by the API available in json-schema format, see the /schema endpoint. Violations of this basic structure are identified and returned in response to a POST to the /query endpoint. There are also additional requirements on the inputs that are not captured by the json-schema definitions. These are identified at evaluation time and reported in the “error” field of the response body to a /result request.

Valid Input

  1. Must be either a json object or json array, failure to meet this requirement will result in:
    • a 400 Bad Request response to the POSTed query; and
    • a response body containing a single “error” field with a string message;
  2. Each json object must conform to the json-schema definition of the inputs, failure to meet this requirement will result in:
    • a 400 Bad Request response to the POSTed query; and
    • a response body containing a single “error” field with a json-array outlining the violations of the json-schema definition;
  3. Further constraints exist for the inputs which are not captured by their json-schema definition, failure to meet these requirements will result in:
    • a 201 CREATED response to the POSTed query; and
    • a 200 OK response to a GET request for the result; however
    • the response body for the result will contain a non-null “error” field detailing the violations – the “result” field will be null.

The most commonly violated additional requirements, those not identified until a query is evaluated, are:

  • Date-time constraints cannot overlap – that is, any specified forced-wake must have ended before another can begin, keeping in mind that any specified lead and lag time are prepended and appended, respectively, to the specified date-times (these lead and lag periods are part of the forced-wake); and
  • start_day must be earlier than the earliest specified date-time.

Other Input Considerations:

  • Date-time format must be YYYY-MM-DDTHH:mm:SS+HH:mm;
  • Forced-wake with a label containing “shift” (eg. shift, day-shift, etc) are treated differently to any forced-wake with a label that does not contain “shift” – sleep recommendations based on alertness optimise over the alertness values predicted during shift.

Duration of the Results

  • All results, whether predictions or recommendations, start from start_time;
  • The end of the duration covered by predictions or recommendations depends on several input fields:
    • If duration_days is not specified as an input then the end will be at the latest specified date-time;
    • If duration_days is specified to a value longer than the last specified date-time then that value is used for the duration covered by the returned results.

Authentication

With the exception of the json-schema definition, all access requires two request parameters for authentication: userName and password. That is, every request must include the equivalent of:

?userName=<yourAPIusername>&password=<yourAPIpassword>

in addition to any other required request or path parameters.

So, for example, using curl at a bash prompt, GET a copy of the main input definition:

API_USER='your_api_username'
read -s -r -p "Enter the password for '$API_USER' >" API_PASSWORD; printf '\n'
curl "https://www.alertnessapi.com/v3/status/{query_id}/?userName=${API_USER}&password=${API_PASSWORD}" | jq .

Note: If you do not have access to jq, remove the | jq . from the end of the curl line.


Endpoints

A complete list of available RESTish endpoints and associated path and request parameters:

  • /v3/schemaGET: a list of the json-schema definitions of the input
  • /v3/schema/{schema_name}GET: a specific json-schema definition;
  • /v3/queryPOST: a new query for the sleep and alertness model;
  • /v3/query/{query_id}GET: an individual, previously POSTed, query;
  • /v3/query/?upload={upload_id}GET: all queries from an upload;
  • /v3/query/?status=RECEIVEDGET: all of a user’s queries with status RECIEVED;
  • /v3/query/?status=QUEUEDGET: all of a user’s queries with status QUEUED.
  • /v3/query/?status=RUNNINGGET: all of a user’s queries with status RUNNING.
  • /v3/query/?status=COMPLETEGET: all of a user’s queries with status COMPLETE.
  • /v3/query/?status=FAILEDGET: all of a user’s queries with status FAILED.
  • /v3/statusGET: a json-array with status information for all of a user’s queries;
  • /v3/status/{query_id}GET: a json-object with status information for a query;
  • /v3/status/?upload={upload_id}GET: a json-array with status information for all queries in an upload;
  • /v3/result/{query_id}GET: an individual result (prediction or recommendation);
  • /v3/result/?upload={upload_id}GET: all results from an upload group.

/schema

The /schema endpoint provides access to the json-schema definitions of the input expected to be POSTed to https://www.alertnessapi.com/v3/query.

The complete input-schema, describing the structure expected for input to the API can be retrieved from:

https://www.alertnessapi.com/v3/schema/api-input

/query

The /query endpoint is the only one to accept both POST and GET requests.

Successfully POSTing a structurally valid query, that conforms to the json-schema definition of the inputs, will return 201 Created with a response body like:

{
  "links": [],
  "content": [
    {
      "links": [
        {
          "rel": "self",
          "href": "https://www.alertnessapi.com/v3/query/42"
        },
        {
          "rel": "status",
          "href": "https://www.alertnessapi.com/v3/status/42"
        }
      ],
      "query_id": 42,
      "upload_id": 13,
      "status": "QUEUED"
    }
  ]
}

NOTE: null fields have been omitted from the above example.

/status

The /status endpoint can be used to GET the status of any previously submitted queries. A single query’s status is accessed using the query_id as a path variable (also available as a link in the response body returned when submitting the query), eg:

https://www.alertnessapi.com/v3/status/42

Successful retrieval of a query’s status will return a 200 OK response, with a response body like:

{
  "links": [
    {
      "rel": "self",
      "href": "https://www.alertnessapi.com/v3/status/42"
    },
    {
      "rel": "query",
      "href": "https://www.alertnessapi.com/v3/query/42"
    },
    {
      "rel": "result",
      "href": "https://www.alertnessapi.com/v3/result/42"
    }
  ],
  "query_id": 42,
  "status": "COMPLETE"
}

NOTE: null fields have been omitted from the above example.

The “status” field can take one of five values:

  • RECEIVED: query has been received as syntactically correct, but has not progressed beyond that status – this should not persist longer than a few tens of milliseconds, if it does it indicates an issue that should be reported to the maintainer;
  • QUEUED: query has been added to the processing queue, but has not yet been evaluated;
  • RUNNING: query is currently being evaluated;
  • COMPLETE: query has completed running (this can include return with identified errors in inputs – see Input section below);
  • FAILED: query has failed to evaluate, this status indicates an unexpected failure during model evaluation, and should be reported to the maintainer.

/result

The result endpoint for a specific query will not exist until the query’s status is COMPLETE. The result for a single query is accessed using the query_id as a path variable (available as a link in the response body returned to a /status request), eg:

https://www.alertnessapi.com/v3/result/42

In addition to “links” and “query_id” fields, the response body to a /result request includes three main top level fields: “input”; “result”; and “error”. The “input” field summarises the inputs used in the model’s evaluation (many unspecified inputs have defaults, which are included here for reference). For a valid query the response will be structured like:

Http code: 200 (OK)

{
  "links": [
    {
      "rel": "raster_outputs_42.png",
      "href": "https://www.alertnessapi.com/v3/result/image/137"
    },
    {
      "rel": "self",
      "href": "https://www.alertnessapi.com/v3/result/42"
    },
    {
      "rel": "query",
      "href": "https://www.alertnessapi.com/v3/query/42"
    }
  ],
  "query_id": 42,
  "input": {...},
  "result": {...}
}

with the “error” field omitted because it is null and where ... indicates that more content would be here. If there were mistakes in the submitted query, beyond those identified by the json-schema definitions (see the following section on Input), the “result” field will be null.

For the structure and contents of the result field see the output-fields and examples pages.


Response

The following are examples of responses sent by the API to a range of common requests, including some that violate expectations for input. NOTE: in the following examples all null fields have been omitted from display.


Example response body to POSTing a successful new request to /query (201 Created):

{
  "links": [],
  "content": [
    {
      "links": [
        {
          "rel": "self",
          "href": "https://www.alertnessapi.com/v3/query/42"
        },
        {
          "rel": "status",
          "href": "https://www.alertnessapi.com/v3/status/42"
        }
      ],
      "query_id": 42,
      "upload_id": 13,
      "status": "QUEUED"
    }
  ]
}

Example response body to GETing the status of a specific request

{
  "links": [
    {
      "rel": "self",
      "href": "https://www.alertnessapi.com/v3/status/42"
    },
    {
      "rel": "query",
      "href": "https://www.alertnessapi.com/v3/query/42"
    },
    {
      "rel": "result",
      "href": "https://www.alertnessapi.com/v3/result/42"
    }
  ],
  "query_id": 13,
  "status": "COMPLETE"
}

Response body when POSTing syntactical invalid json (400 Bad Request):

{
  "links": [],
  "content": [
    {
      "links": [],
      "status": "ERROR",
      "message": "Unable to parse request body, possible json syntax error."
    }
  ]
}

Example response body when POSTing a query that violates the json-schema definition (400 Bad Request):

{
  "links": [],
  "content": [
    {
      "links": [],
      "status": "INVALID",
      "message": "Invalid Query: does not match expected format, specified by json-schema...",
      "schemaViolations": [
        {
          "schemaLocation": "#/definitions/date_time_string",
          "pointerToViolation": "#/start_time",
          "causingExceptions": [],
          "keyword": "format",
          "message": "Not a valid date-time. Text '2017-01-01T24:00:00+10:00' could not be parsed: Invalid value for HourOfDay (valid values 0 - 23): 24."
        }
      ]
    }
  ]
}

In this example the input had two forced-wake specified with the same “start_time”.


Example response body when GETing a result that violates requirements not captured by the json-schema definition:

{
  "links": [
    {
      "rel": "self",
      "href": "https://www.alertnessapi.com/v3/result/342"
    },
    {
      "rel": "query",
      "href": "https://www.alertnessapi.com/v3/query/342"
    }
  ],
  "query_id": 342,
  "input": {
    "start_time": "2017-01-01T00:00:00+10:00",
    "batch_label": "badvalue_overlap_shift",
    "evaluation_type": "predictions",
    "model": "abeysuriya_2018",
    "forced_wake": {
      "end_time": [
        "2017-01-02T22:00:00+10:00",
        "2017-01-03T10:00:00+10:00",
        "2017-01-03T22:00:00+10:00"
      ],
      "start_time": [
        "2017-01-02T12:00:00+10:00",
        "2017-01-02T18:00:00+10:00",
        "2017-01-03T12:00:00+10:00"
      ],
      "lead_duration": 0,
      "label": "shift",
      "lag_duration": 0
    },
    "id": "342",
    "time_zone": "Australia/Brisbane",
    "person_ID": "A-TC-B_42"
  },
  "error": {
    "forced_wake": {
      "time_lead_lag": [
        "BadValue: New forced-wake started when previous one has not yet finished ((start_time(n)-lead_duration) < (end_time(n-1) + lag_duration))."
      ]
    },
    "id": "342"
  }
}

Authentication failures, such as incorrect user name or password return 403 (FORBIDDEN). The response body differing between endpoints, eg:

POST Query Response
{
  "links": [],
  "content": [
    {
      "links": [],
      "status": "UNKNOWN",
      "message": "Authorisation Failure: invalid userName or password"
    }
  ]
}
GET Query Response
{
  "links": [],
  "status": "UNKNOWN"
}
GET Status Response
{
  "links": [],
  "status": "UNKNOWN"
}
GET Result Response
{
  "links": []
}