Quick Start
Learn how to quickly get started with the Keyfax REST based Web API.
This is a quick start guide intended to help developers integrating Keyfax into an existing housing management system or tenant portal. This quick start guide is intended to get you up and running as quickly as possible and as such only details the minimal steps necessary for host systems to launch Keyfax and process Keyfax results.
Some more advanced concepts are not covered in this guide. For further information please refer to the "Additional Reading" section below for links to our full integration documentation.
Verification Methods
Certain requests into the Keyfax REST based Web API require verification. We support 3 types of verification, these are Basic
, Bearer
and API Key
. Verification is achieved by providing a Authorization
header with each request. An example Authorization
header is shown below for each supported verification method.
Basic
Basic
verification is primarily used by native applications or for server-to-server communication where you can secure the private signing key. This is the most secure verification method. All API requests are signed with the private signing key via a pre-flight request to the server and the resulting signature is then sent along with the real request. The signature is then generated again on the server and compared with the sent signature. The public API key must also match.Authorization: Basic {hostName}:{publicKey}:{signature}
Bearer
Bearer
verification is intended for client side scenarios were it's not possible to hide a private key. Bearer tokens are typically short lived. The/api/v1/tokens
end point can be used to generate a short lived JSON web token which can be used with theBearer
verification method. This is the preferred approach to ensure verified client side requests.Authorization: Bearer {hostName}:{bearerToken}
API Key
API Key
uses a static API key to allow requests - this can be used both server and client side. Requests using this approach are not considered verified as the API key could be visible to anyone. We offer this option for those that are not able to execute server side code to generate an initial bearer token for client side requests.Authorization: ApiKey {hostName}:{apiKey}
The hostName
would typically be Default
, Dev
, Test
or Live
depending on the hostName
supplied during initial key creation or when calling /api/v1/key?hostName={hostName}
to create the initial key. (see below).
1. Obtaining a Keyfax API Key
Make a request to /interview/api/v1/key?hostName=Live
to obtain an initial API key. This will provide the response shown below (with different keys)...
{
"apiKey": "63c6310f-51c9-4a06-9a89-c02c069f6802",
"signingKey": "PJ/12L+KHHh99U5PqrdTkBnVpDc3Ykk7uDx6/i5ij57Tc0OWrjiKeEijJnWsYTslD4vg1ewtPjS7LJKVol1dMQ==",
"schemaName": "Basic",
"hostName": "Live"
}
Make a note of the returned apiKey
, signingKey
& hostName
- you will need these for subsequent API requests that require verification. It's worth noting a request to api/v1/key
will only work if keys don't already exists for the supplied host name. If keys already exists for the supplied host name new keys will not be created.
To keep things simple for the rest of this example we'll be using the simplest static API Key
verification method.
2. Returning a Keyfax Launch URL
Once you have your API key you can make verified POST request into /api/v1/startup
supplying Keyfax start-up data to get back a unique URL you can use to launch a Keyfax session. An example request with minimal example Keyfax start-up data is provided below...
POST /api/v1/startup
Headers
Accept: application/json
Authorization: ApiKey Live:63c6310f-51c9-4a06-9a89-c02c069f6802
Content-Type: application/json; charset=utf-8
Body
{
"originatingSystem": {
"value": "PostMon"
},
"company": {
"value": "RDFL_Dev"
},
"mode": {
"value": "RD"
},
"userName": {
"value": "operator"
},
"password": {
"value": "Global"
},
"clientId": {
"value": "ExampleClientId"
},
"scriptSet": {
"id": "scriptSetCode",
"value": "RD"
},
"returnUrl": {
"value": "https://yourkeyfaxurl.com/keyfax-completed?status={0}&co={1}&guid={2}&user={3}"
},
"callerDetails": {
"id": "tenantId",
"attributes": [
{
"key": "isTenant",
"value": "true"
}
],
"children": [
{
"key": "Caller",
"id": "tenantText",
"value": "Mr R Jones, 47 Station Road, Parkstone, Poole, BH14 8UG"
}
]
}
}
The above request will return the following response...
{
"guid": "e728783b-fe9f-40bf-9f39-5329d77161b7",
"launchUrl": "https://yourkeyfaxurl.com/interview/Main/Main.aspx?co=RDFL_Dev&guid=e728783b-fe9f-40bf-9f39-5329d77161b7",
"company": "RDFL_Dev"
}
You can then use the launchUrl
returned within the response to open a Keyfax session for the tenant or agent. The Keyfax session can be opened in the same browser window, a new tab or a separate pop-up window.
Once the tenant or agent has completed the Keyfax script they will be automatically redirected to the returnUrl
supplied within the start-up data provided to Keyfax. When redirecting back to the returnUrl
Keyfax will add a unique identifier to the end of the returnUrl
. This identifier can be used upon the returnUrl
page to obtain Keyfax results.
3. Obtaining Keyfax Results
Upon the user being redirected back to the returnUrl
page you would make the below API request upon the returnUrl
page to retrieve Keyfax results. The GUID within the request body would be obtained from the guid querystring parameter appending to the returnUrl
page.
POST /api/v1/results
Headers
Accept: application/json
Authorization: ApiKey Live:63c6310f-51c9-4a06-9a89-c02c069f6802
Content-Type: application/json; charset=utf-8
Body
{
"guid": "e728783b-fe9f-40bf-9f39-5329d77161b7",
"company": "RDFL_Dev"
}
The /api/v1/results
end-point will return Keyfax results containing all of the information related to the completed Keyfax session. An example response from /api/v1/results
is shown below...
{
"KeyfaxData": {
"Fault": {
"@name": "Fault1",
"@type": "RD",
"IsDeleted": "False",
"IsDirty": "False",
"IsNew": "True",
"Fault_Dialog": "11104",
"Fault_Category": "10763",
"CompanyCode": null,
"ScriptSet": "1",
"FaultText": "Baths: Bath; cracked; tenant action",
"LogDate": "09/08/2022 10:15:18",
"Communal_Type": "",
"Reason_Code": "DT",
"Reason_Text": "DT",
"Recharge": "0",
"Recharge_Code": "RREP",
"Recharge_Cost": "0.00",
"Repair_No": "",
"Repair_Status": "2",
"RTR": null,
"RTR_Date": null,
"Insurance": null,
"Schedule_ID": "operator\\176",
"Site_Visit": "",
"Additional_Info": "",
"Special_Instructions": "",
"Tenancy_Type": "1",
"ClientID": "",
"TenantID": "",
"TenantText": "",
"UserCode": "operator",
"ScriptPath": {
"Question": [
"Q1 = What is the problem with the bath?: A1 = cracked",
"Q2 = Can the bath still be used?: A2 = can be used",
"Q3 = How did it happen?: A3 = tenant action",
"Q4 = Continue logging tenant responsible repair?: A4 = Yes",
"Q5 = Tenant responsibility justifications: A5 = DT"
]
},
"Contractor_Code": "",
"Contractor_Email": null,
"Contractor_Region": null,
"Expenditure_Code": null,
"Nominal_Code": null,
"Job_Code": null,
"Location": null,
"HDIH": null,
"RepairCount": "1",
"AdviceCount": "1",
"CustomCount": "0",
"ActionCount": "0",
"SubActionCount": "0",
"UpdateCount": "0",
"Repair": {
"@name": "Repair1",
"CompleteBy": "06/09/2022 10:15:18",
"ResponseDays": "28",
"Priority": "R",
"PriorityId": "2105",
"RepairCode": "INSP",
"RepairCodeEx": "INSP",
"RepairCodeDesc": "Inspection by Technical Officer",
"UnitOfMeasure": "No",
"UnitOfMeasureQuantity": "1",
"Contractor": "T01",
"IsDeleted": "False",
"IsDirty": "False",
"IsNew": "True"
},
"Advice": {
"@name": "Advice1",
"AdviceCode": "ATR007",
"AdviceCodeEx": "ATR007",
"AdviceCodeDesc": "Landlord not responsible",
"AdvicePlainText": "MSG: Example Paragraph 123 \nExample link within an example paragraph with example link. Example link within an example paragraph with another example link. Links \n Default link msg-text-primary msg-text-secondary msg-text-info msg-text-danger msg-text-warning\n Text \n msg-text-primary msg-text-secondary msg-text-info msg-text-danger msg-text-warning\n Unordered List \n List Item 1 List Item 2 List Item 3\n Ordered List \n List Item 1 List Item 2 List Item 3\n Description List \n List Item 1 List Item 2 List Item 3\n Blockquote \nAn example block quote Code \nvoid Browser_Load(object sender, EventArgs e) Badges \n msg-badge-primary msg-badge-secondary msg-badge-success msg-badge-info msg-badge-danger msg-badge-warning\n Buttons \n msg-btn-primary msg-btn-secondary msg-btn-success msg-btn-info msg-btn-danger msg-btn-warning\n Alerts \nNOTE This alert has the msg-alert-primary class. NOTE This alert has the msg-alert-secondary class. NOTE This alert has the msg-alert-success class. NOTE This alert has the msg-alert-info class. NOTE This alert has the msg-alert-danger class. NOTE This alert has the msg-alert-warning class. Headings \nDefault Heading 1 This is some example text below a header Heading 2 This is some example text below a header Heading 3 This is some example text below a header Heading 4 This is some example text below a header Heading 5 This is some example text below a header Heading 6 This is some example text below a header Primary \nHeading 1 This is some example text below a header Heading 2 This is some example text below a header Heading 3 This is some example text below a header Heading 4 This is some example text below a header Heading 5 This is some example text below a header Heading 6 This is some example text below a header Secondary \nHeading 1 This is some example text below a header Heading 2 This is some example text below a header Heading 3 This is some example text below a header Heading 4 This is some example text below a header Heading 5 This is some example text below a header Heading 6 This is some example text below a header Success \nHeading 1 This is some example text below a header Heading 2 This is some example text below a header Heading 3 This is some example text below a header Heading 4 This is some example text below a header Heading 5 This is some example text below a header Heading 6 This is some example text below a header Info \nHeading 1 This is some example text below a header Heading 2 This is some example text below a header Heading 3 This is some example text below a header Heading 4 This is some example text below a header Heading 5 This is some example text below a header Heading 6 This is some example text below a header Danger \nHeading 1 This is some example text below a header Heading 2 This is some example text below a header Heading 3 This is some example text below a header Heading 4 This is some example text below a header Heading 5 This is some example text below a header Heading 6 This is some example text below a header Warning \nHeading 1 This is some example text below a header Heading 2 This is some example text below a header Heading 3 This is some example text below a header Heading 4 This is some example text below a header Heading 5 This is some example text below a header Heading 6 This is some example text below a header Table Primary \n # First Last Handle 1 Mark Otto @mdo 2 Jacob Thornton @fat 3 Larry the Bird @twitter \n Table Secondary \n # First Last Handle 1 Mark Otto @mdo 2 Jacob Thornton @fat 3 Larry the Bird @twitter \n Table Success \n # First Last Handle 1 Mark Otto @mdo 2 Jacob Thornton @fat 3 Larry the Bird @twitter \n Table Info \n # First Last Handle 1 Mark Otto @mdo 2 Jacob Thornton @fat 3 Larry the Bird @twitter \n Table Danger \n # First Last Handle 1 Mark Otto @mdo 2 Jacob Thornton @fat 3 Larry the Bird @twitter \n Table Warning \n # First Last Handle 1 Mark Otto @mdo 2 Jacob Thornton @fat 3 Larry the Bird @twitter \n Examples \nHeader 1 with Badge NEW Header 2 with Badge UPDATED \nNOTE \nThis is an example of an alert. This alert could be used to draw users attention to important content within a message. NEW Check out what's new - Learn More UPDATED Something updated! WARNING \nFor further information please click this example hyperlink. # First Last Handle 1 Mark Otto @mdo 2 Jacob Thornton @fat 3 Larry the Bird @twitter \n BEFORE PROCEEDING \nThis is an example of an alert. This alert could be used to draw users attention to important content within a message. You can see below an optional link.\n\nLearn More\n FURTHER READING \nThis is an example of an alert. This alert could be used to draw users attention to important content within a message. You can see below optional links.\n\nDownload PDF Open PDF\n\n",
"IsDeleted": "False",
"IsDirty": "False",
"IsNew": "True"
}
},
"GUID": "e728783b-fe9f-40bf-9f39-5329d77161b7",
"Status": "1"
}
}
Host systems would typically perform additional processing of the results produced by Keyfax. For example you may wish to parse the SOR codes or overall priority and associate these with a work item or order within your system.
Example Data
Minimal Start Up Data Examples
The below illustrates the minimum start-up data you must post to Keyfax via /api/v1/startup
. This is only to serve as an example and to show what's possible. Host systems would typically work with Omfax Systems to craft this start-up data based on your specific requirements & configuration.
Staff (RD / FL)
{
"originatingSystem": {
"value": "https://yourdomain.com"
},
"company": {
"value": "Staff_Live"
},
"mode": {
"value": "RD"
},
"userName": {
"value": "operator"
},
"password": {
"value": "Global"
},
"scriptSet": {
"id": "scriptSetCode",
"value": "RD"
}
}
Online (ROL / EOL)
{
"originatingSystem": {
"value": "https://yourdomain.com"
},
"company": {
"value": "Online_Live"
},
"mode": {
"value": "ROL"
},
"userName": {
"value": "KFROL_User"
},
"password": {
"value": ""
},
"scriptSet": {
"id": "scriptSetCode",
"value": "ROL"
}
}
Full Start- Up Data Examples
The below illustrates some realistic start-up data you would typically post to Keyfax via /api/v1/startup
. This is only to serve as an example and to show what's possible. Host systems would typically work with Omfax Systems to craft this start-up data based on your specific requirements & configuration.
Staff (RD/FL)
{
"originatingSystem": {
"value": "https://yourdomain.com"
},
"company": {
"value": "Staff_Live"
},
"mode": {
"value": "RD"
},
"scriptSet": {
"value": "RD"
},
"userName": {
"value": "operator"
},
"password": {
"value": "Global"
},
"returnUrl": {
"value": "https://yourdomain.com/keyfax-completed?status={0}&co={1}&guid={2}&user={3}"
},
"tenant": {
"value": "James Sopher, 12 Teal Road, Parkstone, Poole, Dorset, BH14 8UB"
},
"assetId": {
"value": "T20"
},
"callerDetails": {
"children": [
{
"key": "CallerID",
"value": "CE21A"
},
{
"key": "FirstName",
"value": "James"
},
{
"key": "LastName",
"value": " Sopher"
},
{
"key": "CallerEmail",
"value": "[email protected]"
},
{
"key": "Mobile",
"value": "07555 499877"
},
{
"key": "DOB",
"value": "1987-05-24T00:00:00.000Z"
},
{
"key": "Vulnerable",
"value": "N"
},
{
"key": "MobilityIssues",
"value": "N"
},
{
"key": "Vulnerability",
"value": ""
},
{
"key": "GenderPronoun",
"value": "he/him"
},
{
"key": "Financials",
"children": [
{
"key": "Rent",
"value": 145
},
{
"key": "CurrentBalance",
"value": 345
}
]
}
]
},
"tenancyDetails": {
"children": [
{
"key": "TenureType",
"value": "Assured"
},
{
"key": "HousingOfficer",
"value": "Tina Jones"
}
]
},
"property": {
"children": [
{
"key": "AddressLine1",
"value": "12 Teal Road"
},
{
"key": "AddressLine2",
"value": "Parkstone"
},
{
"key": "AddressLine3",
"value": "Poole"
},
{
"key": "AddressLine4",
"value": "Dorset"
},
{
"key": "AddressLine5",
"value": "BH14 8UB"
},
{
"key": "HeatingType",
"value": "Gas"
},
{
"key": "ComponentData",
"children": [
{
"key": "Component",
"children": [
{
"key": "Type",
"value": "Gas Boiler"
},
{
"key": "Make",
"value": "Worcester"
},
{
"key": "Model",
"value": "Greenstar 30"
},
{
"key": "InstallDate",
"value": "2020-03-24T00:00:00.000Z"
},
{
"key": "WarrantyPeriod",
"value": "24"
},
{
"key": "WarrantyExpiryDate",
"value": "2022-03-24T00:00:00.000Z"
},
{
"key": "NextServiceDate",
"value": "2035-03-24T00:00:00.000Z"
}
]
}
]
},
{
"key": "PlannedMaintenance",
"children": [
{
"key": "PMJob",
"children": [
{
"key": "ProgrammeDescription",
"value": "Windows"
},
{
"key": "NextPlannedDate",
"value": "03/01"
}
]
}
]
}
]
}
}
Online (ROL/EOL)
{
"originatingSystem":{
"value":"https://yourdomain.com"
},
"company":{
"value":"Online_Live"
},
"mode":{
"value":"ROL"
},
"scriptSet":{
"value":"ROL"
},
"userName":{
"value":"KFROL_User"
},
"password":{
"value":""
},
"returnUrl":{
"value":"https://yourdomain.com/keyfax-completed?status={0}&co={1}&guid={2}&user={3}"
},
"tenant":{
"value":"James Sopher, 12 Teal Road, Parkstone, Poole, Dorset, BH14 8UB"
},
"assetId":{
"value":"T20"
},
"callerDetails":{
"children":[
{
"key":"CallerID",
"value":"CE21A"
},
{
"key":"FirstName",
"value":"James"
},
{
"key":"LastName",
"value":" Sopher"
},
{
"key":"CallerEmail",
"value":"[email protected]"
},
{
"key":"Mobile",
"value":"07555 499877"
},
{
"key":"DOB",
"value":"1987-05-24T00:00:00.000Z"
},
{
"key":"Vulnerable",
"value":"N"
},
{
"key":"MobilityIssues",
"value":"N"
},
{
"key":"Vulnerability",
"value":""
},
{
"key":"GenderPronoun",
"value":"he/him"
},
{
"key":"Financials",
"children":[
{
"key":"Rent",
"value":145
},
{
"key":"CurrentBalance",
"value":345
}
]
}
]
},
"tenancyDetails":{
"children":[
{
"key":"TenureType",
"value":"Assured"
},
{
"key":"HousingOfficer",
"value":"Tina Jones"
}
]
},
"property":{
"children":[
{
"key":"AddressLine1",
"value":"12 Teal Road"
},
{
"key":"AddressLine2",
"value":"Parkstone"
},
{
"key":"AddressLine3",
"value":"Poole"
},
{
"key":"AddressLine4",
"value":"Dorset"
},
{
"key":"AddressLine5",
"value":"BH14 8UB"
},
{
"key":"HeatingType",
"value":"Gas"
},
{
"key":"ComponentData",
"children":[
{
"key":"Component",
"children":[
{
"key":"Type",
"value":"Gas Boiler"
},
{
"key":"Make",
"value":"Worcester"
},
{
"key":"Model",
"value":"Greenstar 30"
},
{
"key":"InstallDate",
"value":"2020-03-24T00:00:00.000Z"
},
{
"key":"WarrantyPeriod",
"value":"24"
},
{
"key":"WarrantyExpiryDate",
"value":"2022-03-24T00:00:00.000Z"
},
{
"key":"NextServiceDate",
"value":"2035-03-24T00:00:00.000Z"
}
]
}
]
},
{
"key":"PlannedMaintenance",
"children":[
{
"key":"PMJob",
"children":[
{
"key":"ProgrammeDescription",
"value":"Windows"
},
{
"key":"NextPlannedDate",
"value":"03/01"
}
]
}
]
}
]
}
}
Custom Start-Up Data
You can supply custom / non-standard fields within the Keyfax start-up JSON using the customData
property as shown below...
"customData": {
"key": "CustomRoot1",
"children": [
{
"key": "CustomRoot1_Child1",
"value": "Child 1 Value",
},
{
"key": "CustomRoot1_Child2",
"value": "Child 2 Value",
}
]
}
This will be converted to the following start-up XML...
<CustomRoot1>
<CustomRoot1_Child1>Child 1 Value</CustomRoot1_Child1>
<CustomRoot1_Child2>Child 2 Value</CustomRoot1_Child2>
</CustomRoot1>
This would then be accessible within Keyfax via Import Databoxes (i.e. Startup/CustomData/CustomRoot1/CustomRoot1_Child1/text()
would return "Child 1 Value").
You can also nest custom properties as demonstrated below...
"customData": {
"key": "CustomProperty",
"children": [
{
"key": "Children",
"children": [
{
"key": "Child1",
"value": "Child 1 Value",
},
{
"key": "Child2",
"value": "Child 2 Value",
}
]
}
]
}
This will produce the following start-up XML...
<CustomProperty>
<Children>
<Child1>Child 1 Value</Child1>
<Child2>Child 2 Value</Child2>
</Children>
</CustomProperty>
Custom Start Up Data Example
Consider the following start-up JSON...
{
"originatingSystem": {
"value": "LaunchExample"
},
"company": {
"value": "LiveWest_Online_Test"
},
"mode": {
"value": "ROL"
},
"userName": {
"value": "KFROL_User"
},
"password": {
"value": ""
},
"returnUrl": {
"value": "http://keyfaxtest.com:8011/Completed.html?status={0}&co={1}&guid={2}&user={3}"
},
"assetId": {
"value": "0"
},
"clientId": {
"value": "0"
},
"customData": {
"key": "CustomData",
"children": [
{
"key": "TenancyTypeDescription",
"value": "Example tenancy type description"
},
{
"key": "CategoryTypeDescription",
"value": "Example category type description"
},
{
"key": "ActualHandoverDate",
"value": "2023-06-01"
}
]
}
}
This would actually be supplied to Keyfax as XML in the form...
<KeyfaxData>
<Startup>
<OriginatingSystem>LaunchExample</OriginatingSystem>
<Mode>ROL</Mode>
<UserName>KFROL_User</UserName>
<Password />
<Company>LiveWest_Online_Test</Company>
<ClientId>0</ClientId>
<ReturnURL>
<![CDATA[http://keyfaxtest.com:8011/Completed.html?status={0}&co={1}&guid={2}&user={3}]]>
</ReturnURL>
<AssetID>0</AssetID>
<CustomData>
<TenancyTypeDescription>Example tenancy type description</TenancyTypeDescription>
<CategoryTypeDescription>Example category type description</CategoryTypeDescription>
<ActualHandoverDate>2023-06-01</ActualHandoverDate>
</CustomData>
<GUID>
<![CDATA[9f360185-82a1-4121-aa5b-ca3d0f4e1452]]>
</GUID>
<ScriptSet>
<![CDATA[ROL]]>
</ScriptSet>
<ROLDetail>
<![CDATA[]]>
</ROLDetail>
</Startup>
</KeyfaxData>
So to access values within the <CustomData/>
element you can use XPath expressions within existing Import Databoxes as shown below...

For additional information please see our Deep Diveor API Reference.
Last updated