Subscriber Event API API
Subscriber Event API 1.2.5
OAS3
Introduction
This service allows a partner application to receive notifications of subscribed events generated by Keyloop dealer systems. The process of subscribing to the event streams is currently managed by Keyloop.
The event notification payloads sent to the subscriber end-point will contain metadata which should be sufficient for basic filtering and to allow for subsequent queries to be built to obtain the associated object. For example...
- A notification of an event is received which was..
- ...performed on a customer object
- ...an update to the customer (I.e. a save of an existing customer record)
- ...in relation to customer object XYZ-123
- ...performed on system ABC/987
- The subscriber may then choose to use the Keyloop partner program suite of APIs to perform subsequent actions.
- GET /ABC/987/v1/customer/XYZ-123
Change History
[1.2.4] - Change Event response change
- Success response code changed from 201 to 204
[1.2.5] - Move header parameters to payload. Add message contextual information
- Removed enterprise-id, store-id, origin-id and origin-application from the header parameters.
- Added objects context and origin to the payload schema
- Added enterpriseId, storeId, provider and dealerCode to the context object
- Added id and application to the origin object
Notes
The events broadcast to the subscriber end-point are...
- ...limited to those from Keyloop systems/locations which the partner has subscribed to.
- ...limited to those for business objects (E.g. customer, repair order) the partner has subscribed to.
- ...not guaranteed to be delivered in chronological order.
- ...bound by a Keyloop re-try policy. If the end-point is not reachable within that policy the event will not be sent.
Implementation Guide
This API specification is a guide for Keyloop partners to implement internet accessible end-point services to allow the streaming of business events generated from Keyloop dealer systems & applications.
Security
The provider of the service may implement one of two security models.
- OAuth2.0 Client Credentials Flow (recommended)
- Basic Authentication
OAuth
It is expected that the provider of the service implements an OAuth2.0 authorisation mechanism. The grant type must be client credentials. OAuth2.0 is widely used and further details can be found here for RFC6749 or here for a summarised explanation. Once the authorisation service has been implemented certain information must be shared with Keyloop. The following are required to obtain an authorisation token...
- Client id - The unique id assigned by the provider to Keyloop as an authorised consumer.
- Client secret - The secret or key which accompanies the client id.
- Scope - the scope of the authorisation (optional)
- Authorisation end-point - the end-point the client must call, supplying the client id/secret, in order to receive a token in response.
Authorisation Example
Request Format (curl)
curl --location --request POST 'https://<host>/<path>' --header 'Authorization: Basic <Base64 encoding of client id/secret>' --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'grant_type=client_credentials' --data-urlencode 'scope=<scope>'
Response Format (JSON)
{
"token_type": "BearerToken",
"access_token": "ISJiyywgDUessZXDA0URQjjlMwZ0",
"scope": "",
"expires_in": "3599",
"refresh_count": "0",
"status": "approved"
}
Token
The access token returned after successful authorisation will have an expiration set. It is recommended that the token expires after 1 hour (3600 seconds). The access token will be used in the Bearer parameter for subsequent API calls.
Basic Authentication
Basic authentication requires the service provider to share a user name and a key with the client. The client will authenticate by providing an encoded combination of the user name and key in the HTTP header over an encrypted protocal (HTTPS).
The key should be at least 20 characters in length.
Authorisation Example
The service provider supplies credentials:
- user name = TrustedClient
- key = jfuenbUYRBjitB5644fgBDTijnT644g6ij
The client will call the service providing an additional HTTP header with a Base64 encoded string of the user name, a colon (:) and the key - TrustedClient:jfuenbUYRBjitB5644fgBDTijnT644g6ij
Authorization: Basic VHJ1c3RlZENsaWVudDpqZnVlbmJVWVJCaml0QjU2NDRmZ0JEVGlqblQ2NDRnNmlq
Message Signing
Where basic authentication is used the event messages will be signed according to IETF draft 10 of Signing HTTP Messages. The messages have a Signature HTTP header whichs includes reference to RSA public key and headers needed to generate the signature.
For example the header may be signed...
Signature: keyId="key-2020-a",algorithm="rsa-sha256",headers="(request-target) host date content-length content-md5",signature="a secure signature"
In that case the signature would be generated based on BASE64-encoded string of said headers (with header names in lowercase) on separate lines in the specified order:
(request-target): post /callback-recipients-page\n
host: www.callback-receiver.com\n
date: Mon, 02 Jul 2018 07:56:47 GMT\n
content-length: 1234\n
content-md5: 47bce5c74f589f4867dbd57e9ca9f808
The location of the public key required to validate the signature is included in the header.
Keyloop will initially provide the public key on request, but intend to offer via an API in the future.
Environments
Keyloop recommends that the specification is implemented in a minimum of two discrete environments:
- Test - For the purpose of communicating evaluation/testing data only
- Production - Services which are dedicated to managing 'live' data only
The provider of the service will share the service end-points for these environments with Keyloop. The test environment will be used to perform a certification exercise before events are sent to the production service.
Ping
Purpose
The ping API is used by a client to check reachability of the host.
Implementation
If the host is successfully contacted a response code 200 will be returned. All other responses will be treated by the client as the host being unavailable, in which case all event notifications will be suspended.
Event
Purpose
The Event API provides a standardised interface contract for Keyloop to stream business object event notifications to interested parties (subscribers). The operations are limited to a simple POST (create) of a notification.
Implementation
If the client sends a valid notification to the service a response code 201 will be expected to be returned. Any other response codes will be interpreted as failures and initiate a re-try policy at the client-side.
Re-Try Policy
The re-try mechanism will provide a degree of resilience to the event subscription service. The policy is currently being defined by Keyloop. However, it will be governed by a maximum number of retries within an associated time-period. Once either condition has been exceeded the no further deliveries will be attempted.
Enumerations
Enumerated values are used within the event notification payload. Enumerations help to reduce ambiguity and clearly state the range of permitted values. It is important to note that Keyloop may extend the range of values in some of the attributes (E.g. Entity types) without prior notification to service providers. As such the service provider should ensure that the implementation of enumerated attributes is suitably flexible to accommodate unexpected values without generating error responses.
Header Parameters
- correlation-id
A unique identifier value (GUID) that allows reference to a particular transaction or event chain. This ID will always be provide by Keyloop.
Request Body
- eventId
A unique identifier value (GUID) for the event. - createdAt
The timestamp of the event creation. - eventType
A code representing the type of event which occurred which may be one of created, updated or deleted. Additional event types may be added in future. - context
Contextual information used for filtering and routing- enterpriseId
This value will be populated with the corresponding enterprise id - storeId
This value will be populated with the corresponding store id - provider
If available this value will be populated with the corresponding provider identifier - dealerCode
If available this value will be populated with the corresponding dealer code/id
- enterpriseId
- entity
Attributes associated with the entity/object the event occured to.- id
A unique identifier for the specific business object the event occurred to. - type
A code representing the type business object the event occurred to. For example, CUSTOMER. - origin
Information relating to the origin of the event- id
The unique id of the system which generated the event - application
The class of application which generated the event
- id
- properties
Additional properties may be provided to supplement the general event content. These properties may vary based on object type (E.g. REPAIR_ORDER)- propertyType
A code which is use to determine which set of additional properties should be used based in the event's entity. - url
A URL that identifies the location where the business object payload may be retrieved. This is included for future use and is not currently supplied. - repairOrderState (only included in REPAIR_ORDER entity events)
A code representing the transaction state of the repair order object. Values are:
- appointmentchanged - When a customer appointment is changed. Note that this event is sent only when a booked event was sent at an earlier point in time.
- appointmentcancelled - When an appointment is cancelled. Note that this event is sent only when a booked event was sent at an earlier point in time.
- awaitingauthorization - When one of the repair order lines or items requires to be authorised first before it can be progressed.
- awaitinglabor - When one of the repair order lines or items is set to a status that indicated that more labor is required.
- awaitingparts - When one of the repair order lines or items is set to a status that indicates that parts are required before the work can continue. Note that also parts lines that reach a backorder status will trigger this event.
- booked - When a customer appointment is made.
- cancelled - Repair order was cancelled.
- checkedin - When a vehicle is checked in at a dealership.
- checkedout - When the customer collects the vehicle.
- closed - Repair order was completely closed.
- created - When a repair order for a vehicle (and potentially a customer) is created.
- onhold - When a repair order is put on hold awaiting for example parts or instructions.
- released - When a repair order is released after being in a state of onhold. Note that this event should be sent in addition to the event of the new repair order state.
- readyforcollection - When the customer is contacted to confirm work completion.
- updated - Repair order was updated.
- vehiclecheckcompleted - When the check of the vehicle on the repair-order is completed.
- workcompleted - When work on the vehicle is complete.
- workstarted - When the first technician starts work on the vehicle. For example by clocking onto the repair order.
- workstopped - When the last technician stops work on the vehicle. For example by clocking off from the repair order.
- workrestarted - When the first technician restarts work on the vehicle, after it was previously stopped.
- propertyType
- id
EventsPost Events
Post Events
Intended Use
This end-point can be used to check if the connection to back-end system is healthy.
Parameters
No parameters
Responses
Code | Description | Links |
200 | Ping response Media typeControls Accept header.{
"code": "200",
"message": "Endpoint OK. The endpoint responded in 161 ms"
} | No links |
Called by Keyloop, this action will receive a new event for any subscribed object
Parameters
Name | Description |
---|---|
correlation-id * string (header) | The correlation-id assigned by the event source system |
Signature string (header) | Message signature (only used with Basic Authentication) |
Request body
Event item to create
{
"eventId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"createdAt": "2016-08-29T09:12:33.001Z",
"eventType": "UPDATED",
"context": {
"enterpriseId": 12345,
"storeId": 9876,
"provider": "Morgan",
"dealerCode": "AB12345"
},
"entity": {
"id": "b951eb58-61a6-41ef-8dcd-6e7d0d3ef16b",
"type": "CUSTOMER",
"origin": {
"id": "b951eb58-61a6-41ef-8dcd-6e7d0d3ef16c",
"application": "Automaster"
},
"properties": {
"propertyType": "DEFAULT",
"url": "https://www.exampledatabase.com/specificEvent"
}
}
}
Responses
Code | Description | Links |
204 | Event notification created | No links |
400 | invalid input, object invalid | No links |