Webhooks

Webhooks are an alternative way to receive assessment results from the API. Instead of an API client calling the text/ID/results endpoint, the API system can notify an endpoint of the API client's choosing with the assessment results when assessment is completed.

First, a webhook endpoint needs to be configured so that the API knows where notifications should be sent. This will also create and return a secret, which the API will use to sign notifications that it sends. Once a webhook endpoint has been defined, and assuming the endpoint has been implemented within the API client's system, it will receive notifications signed using the secret.

Configuring webhooks

Webhook configuration can be performed by API clients using endpoints to create, list and delete webhook configurations.

Creation

A webhook configuration can be created by calling a creation endpoint, supplying the URL of the endpoint which the API client wants to receive notifications on.

Request

Method and URI:

POST /VERSION/account/ACCOUNT_ID/webhooks

Request parameters:

Parameter Required? Description
version Yes The desired API version.
account_id Yes Your API account ID.

Request body JSON:

{"url": "https://endpoint-host/endpoint"}

The attribute values are as follows:

Attribute name Required? Format Description
url Yes An HTTPS URL with maximum 255 characters The URL of the endpoint which should receive notifications.

Response

Successful creation

HTTP status code: 200

Response body JSON:

{"type":"success","id":"589b39e3-e279-4993-b8bf-7817db5135f9","secret":"an-autogenerated-secret","code":200}

The id can be used to refer to the webhook if wanting to delete it. The secret should be stored securely and is needed to verify the signature provided with webhook notifications sent by the API system.

Failed creation

Creation can fail for a number of reasons. The general response format is as follows:

HTTP status code: 400

Example response body JSON:

{"type": "error", "code": 400, "message": "url must be https"}

type is always "error". The message attribute value can vary depending on the specific error as shown by the examples below.

Error Code Example message
URL is missing. 400 "url is missing"
URL attribute is present but has blank value. 400 "url is blank"
URLs must use https. 400 "url must be https"
URL is missing a host. 400 "url is missing host section"
URL is invalid. 400 "url is not a valid URL"

Some errors can occur before the validation of each attribute is performed:

Error Code Message Additional attributes
The request body is not valid JSON 400 invalid_json
The request body contains byte sequences which are not valid UTF-8 400 invalid_encoding invalid_attributes: an array of invalid attribute names, with invalid byte sequences encoded using \xHH notation, where H is a hex digit. For example: "invalid_attributes": ["attrib\xC2ute1", "attrib\xE3\x80ute2"]
invalid_values: a JSON object where the attributes are the attributes with invalid values and the values are the invalid values, with invalid byte sequences encoded using \xHH notation, where H is a hex digit. For example: "invalid_values": {"attribute1": "Val\xC2ue 1", "attrib\xE3\x80ute2": "Val\xC2ue 2"} with the second element showing the case where both an attribute name and its value happen to contain invalid UTF-8 (the attribute name would also appear in the invalid_attributes array).

Listing

A list of currently-configured webhooks can be obtained for reference.

Request

Method and URI:

GET /VERSION/account/ACCOUNT_ID/webhooks

Request parameters:

Parameter Required? Description
version Yes The desired API version.
account_id Yes Your API account ID.

Response

HTTP status code: 200

Response body JSON:

{"type":"success","webhooks":[{"id":"589b39e3-e279-4993-b8bf-7817db5135f9","url":"https://your-endpoint-host/your_endpoint"}],"code":200}

The id can be used to refer to the webhook if wanting to delete it.

Deletion

A webhook configuration can be deleted so that the endpoint will no longer receive notifications from the API system.

Request

Method and URI:

DELETE /VERSION/account/ACCOUNT_ID/webhooks/ID

Request parameters:

Parameter Required? Format Description
version Yes The desired API version.
account_id Yes Your API account ID.
id Yes The ID of the webhook configuration to be deleted. The ID to use is the one returned by the webhook creation and listing API endpoints for the webhook to be deleted.

Response

Successful deletion

HTTP status code: 200

Response body JSON:

{"type":"success","code":200}
Failed deletion

Deletion can fail if a webhook configuration is not found for the specified ID. The response format is as follows:

HTTP status code: 404

Response body JSON:

{"type": "error", "code": 404, "message": "webhook not found"}

Handling webhook notifications

When a webhook has been configured, the API system will send a notification when a piece of text has completed assessment.

Endpoint requirements

The API client's webhook endpoint should return a 2xx code if it successfully dealt with the notification. It should be implemented such that it can cope with multiple calls for the same notification. (The API system may make multiple calls if it can't tell if a call succeeded, for example, because of a network problem.) If the webhook endpoint returns a 5xx error the webhook notification will retry a few times over the next 15 minutes, then backing off to hourly attempts, and then giving up after 24 hours have elapsed. If the signature verification fails as described later in this section, the endpoint should return a 401 or 403 status.

Notification format

The notification is sent in JSON in the following format in the request body:

{"type":"text_assessment",
 "parameters":{"account_id":"ACCOUNT_ID","id":"ID"},
 "notification":{
     "type": "success", "code": 200, "overall_score": 7.3,
     "score_dimensions": {"prompt_relevance": 3.0},
     "sentence_scores": [[0, 5, -0.23], [6, 42, 0.56]],
     "suspect_tokens": [[0, 5], [40, 42]],
     "textual_errors": [[0, 5, "Greetings", "S"], [32, 35, "the", "MD+"]],
     "text_stats": {"r1": 0.333333, "r2": 0.103448, "r3": 0.0, "lcs": 7.0, "feature_count": 344.0, "word_count": 36.0}
 }
}

The elements are as follows:

Attribute name Format Description
type always "text_assessment"
parameters JSON object Two attributes: account_id is the account id of the account which originally submitted the piece of text; id is the submission id of the piece of text which this notification relates to.
notification JSON object A results object in the same format as a response to the /results API endpoint.

Receiving Notifications

Once the end point is configured, the API system will start sending notifications to it as text submissions complete their assessment. It is important that the signature of each message is verified to be sure it is a genuine result from the API system and not an imposter. The ELiT-Signature header contains a timestamp and one or more signatures. The timestamp is prefixed by t=, and each signature is prefixed by a scheme. Schemes start with v, followed by an integer. Currently, the only valid signature scheme is v1. There may be more than one signature although under normal circumstances there will only be one. However, the client endpoint should be implemented to cope with more than one v1 signature. If at least one matches then the message is correctly signed.

An example of an ELiT-Signature is:

ELiT-Signature: t=1492774577,
                v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd,
                v1=6ffbb59b2300aae63f272406069a9788598b792a944a07aba816edb039989a39

Note that newlines have been added in the example above for clarity. A real ELiT-Signature header will be one line.

The API system generates signatures using a hash-based message authentication code HMAC with SHA-256. To prevent downgrade attacks, all schemes that are not v1 should be ignored.

To verify the signature follow these steps:

Step 1: Extract the timestamp and signatures from the header

Split the header using the , character as the separator to get a list of elements. Then split each element using the = character as the separator to get a prefix and value pair.

The value for the prefix t corresponds to the timestamp, and v1 corresponds to the signature(s). All other elements can be discarded.

Step 2: Prepare the signed-payload string

This is achieved by concatenating:

  • The timestamp (as a string)
  • The character .
  • The actual JSON payload (i.e. the request’s body)

Step 3: Determine the expected signature

Compute an HMAC with the SHA256 hash function. Use the endpoint’s signing secret as the key and use the signed-payload string as the message.

Step 4: Compare signatures

Compare the signature(s) in the header to the expected signature. If a signature matches, compute the difference between the current timestamp and the received timestamp, and decide if the difference is within tolerance. The timestamp is the number of milliseconds since the epoch time (1970-01-01 00:00:00 UTC) using an approach not subject to the 2038 problem.

To protect against timing attacks, use a constant-time string comparison to compare the expected signature to each of the received signatures.

If the signature verification fails, the endpoint should return a 401 or 403 status.

results matching ""

    No results matching ""