REST API
QBench API v1.0 Documentation
Overview
QBench uses OAuth 2.0 standards and token based authentication when making requests. To gain access to the QBench REST API, you must first create a client and obtain a client ID and client secret in the developer tab of the QBench general settings page. You must select Server-Side Web Application when creating your client in order to use this authorization flow.
Then, your application prepares to make authorized API calls by using the client ID and client secret to request an access token from the auth server.
Finally, your application can use the access token to call QBench API endpoints.
Preparing to make an authorized API call
After you obtain the client ID and client secret from the developer tab, your application needs to complete the following steps:
- Create a JSON Web Token(JWT), which includes a header, a claim set, and a signature.
- Request an access token.
- Handle the JSON response that the server returns.
If the response includes an access token, you can use the access token to call the QBench API. (If the response does not include an access token, your JWT and token request might not be properly formed, or may include invalid credentials.)
When the access token expires, your application will need to generate another JWT, sign it, and requests another access token.
Creating a JWT
A JWT is composed of three parts: a header, a claim set, and a signature. The header and claim set are JSON objects. These JSON objects are serialized to UTF-8 bytes, then encoded using the Base64url encoding. This encoding provides resilience against encoding changes due to repeated encoding operations. The header, claim set, and signature are concatenated together with a period (.) character.
A JWT is composed as follows:
{Base64url encoded header}.{Base64url encoded claim set}.{Base64url encoded signature}
The base string for the signature is as follows:
{Base64url encoded header}.{Base64url encoded claim set}
Forming the JWT header
The header consists of two fields that indicate the signing algorithm and the format of the assertion. Both fields are mandatory, and each field has only one value.
QBench authorization relies on the HMAC-SHA256 algorithm and the JWT token format. As a result, the JSON representation of the header is as follows:
{"alg":"HS256","typ":"JWT"}
The Base64url representation of this is as follows:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Forming the JWT claim set
The JWT claim set contains information about the JWT, including the client ID, the time the token was issued, and the lifetime of the token. These fields are mandatory. Like the JWT header, the JWT claim set is a JSON object and is used in the calculation of the signature.
Required claims
The required claims in the JWT claim set are shown below. They may appear in any order in the claim set.
Name |
Description |
sub |
The client ID from the developer tab. |
iat |
The time the assertion was issued, specified as seconds since 00:00:00 UTC, January 1, 1970. |
exp |
The expiration time of the assertion, specified as seconds since 00:00:00 UTC, January 1, 1970. This value has a maximum of 1 hour after the issued time. |
The JSON representation of the required fields in a JWT claim set is shown below:
{
"iat":1491596166,
"sub":"client_id",
"exp":1491598166
}
Encoding the JWT claim set
Like the JWT header, the JWT claim set should be serialized to UTF-8 and Base64url-safe encoded. Below is an example of a Base64url representation of a JWT Claim set from above:
eyJpYXQiOjE0OTE1OTYxNjYsInN1YiI6ImNsaWVudF9pZCIsImV4cCI6MTQ5MTU5ODE2Nn0
Computing the signature
JSON Web Signature (JWS) is the specification that guides the mechanics of generating the signature for the JWT. The input for the signature is the byte array of the following content:
{Base64url encoded header}.{Base64url encoded claim set}
The signing algorithm in the JWT header must be used when computing the signature. The only signing algorithm supported by the QBench is the HMAC-SHA256 hashing algorithm. This is expressed as HS256 in the alg field in the JWT header.
Sign the UTF-8 representation of the input using HMAC-SHA256 with the client secret obtained from the QBench developer tab. The output will be a byte array.
The signature must then be Base64url encoded. The header, claim set, and signature are concatenated together with a period (.) character. The result is the JWT. It should be the following (line breaks added for clarity):
{Base64url encoded header}.
{Base64url encoded claim set}.
{Base64url encoded signature}
Below is an example of a JWT before Base64url encoding:
{"alg":"HS256","typ":"JWT"}.
{
"iat":1491596166,
"sub":"client_id",
"exp":1491598166
}.
[signature bytes]
Below is an example of a JWT that has been signed and is ready for transmission:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0OTE1OTYxNjYsInN1YiI6ImNsaWVudF9pZCIsImV4cCI6MTQ5MTU5ODE2Nn0.pdAKb30OOltLe0WvjJYl4_mwt50ylZQKlz_047aFNeY
Making the access token request
After generating the signed JWT, an application can use it to request an access token. This access token request is an HTTPS POST request, and the body is URL encoded. The URL is shown below, where <qbench-url> is the qbench URL that has been provided to you for your company:
<qbench-url>/qbench/oauth2/v1/token
The following parameters are required in the HTTPS POST request:
Name |
Description |
grant_type |
Use the following string, URL-encoded as necessary: urn:ietf:params:oauth:grant-type:jwt-bearer |
assertion |
The JWT, including signature. |
Below is a raw dump of the HTTPS POST request used in an access token request, where <qbench-url> is the qbench URL that has been provided to you for your company:
POST /qbench/oauth2/v1/token HTTP/1.1
Host: <qbench-url>
Content-Type: application/x-www-form-urlencoded
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0OTE1OTYxNjYsInN1YiI6ImNsaWVudF9pZCIsImV4cCI6MTQ5MTU5ODE2Nn0.pdAKb30OOltLe0WvjJYl4_mwt50ylZQKlz_047aFNeY
Handling the response
If the JWT and access token request are properly formed and contain valid credentials, then the JSON response from the server includes an access token. The following is an example response:
{
"access_token": "63ff42c5-49e6-42e2-bc3f-04fbfc22bbcb",
"token_type": "Bearer",
"expires_in": 3600
}
Access tokens expire in one hour and can be reused until they expire.
Calling the QBench API
After your application obtains an access token, you can use the token to make calls to a the QBench API. To do this, include the access token in a request to the API by including either an access_token query parameter or an Authorization: Bearer HTTP header. When possible, the HTTP header is the preferable means of sending the token.
Examples
In the following examples, <qbench-url> represents the QBench URL that has been provided to you for your company.
A call to the sample endpoint using the Authorization: Bearer HTTP header might look like the following, though you'll need to specify your own valid access token::
GET /qbench/api/v1/sample/1234 HTTP/1.1
Authorization: Bearer 63ff42c5-49e6-42e2-bc3f-04fbfc22bbcb
Host: <qbench-url>
Here is a call to the same API using the access_token query string parameter:
GET <qbench-url>/qbench/api/v1/sample/1234?access_token=63ff42c5-49e6-42e2-bc3f-04fbfc22bbcb
When access tokens expire
Access tokens expire one hour after they are issued. When an access token expires, the application should generate another JWT, sign it, and request another access token.
A note about Date/Times and timezones
All Date/Time values that are sent and received via the QBench API are assumed to be in UTC by default. Any timezone conversions that are required by the third-party will need to be done outside of the QBench API. However, if you specify a timezone header `X-Timezone=America/Los_Angeles`, timezone conversions will take place server-side. A list of available timezone parameters are located here
Reason Required
QBench Administrators can configure a field to require a reason when being updated. Suppose we want to update a Sample's Description field, but a reason is required to update this field. When this is the case, the API will response with a 400 error and a payload like this:
{
'data': {
'66842': [
{
'custom_formatted_id': '66842',
'display_name': 'Description',
'field_name': 'description'
}]
},
'message': 'A reason is required to update this data',
'qb_error_code': 'REASON_REQUIRED',
'qb9164': '7eb6b',
'status_code': 400
}
In this example, the API was trying to update a Sample's Description but a reason is required to update the Description. To include a reason, simply include a new key value pair in your request payload like this:
{
'id': 123,
'description': 'New Description',
'qbench_update_reason': 'We needed to update the description.'
}
Note: If your update payload is a list of items to update, you must include the "qbench_update_reason" with the entities that have fields that need a reason to be updated.
Filtering on Additional Fields
Filters for additional fields require a bit more work. For the supported endpoints with additional field filtering, you will need to base64-encode a JSON object with your parameters. Here is an example of how to filter each additional field type:
const params = {
// Number Field Filter
"addl_number":"12",
"addl_number_actionButton":"<", // ["Default", "<", ">", "=", "Range", "Set"]
// Number Field Filter (Set)
"addl_number_tags": [1, 2, 3],
"addl_number_actionButton":"Set",
// Number Field Range
"addl_number_lowerLimit":1,
"addl_number_upperLimit":5,
"addl_number_actionButton":"Range",
// Text Field Filter
"addl_text":"TEXT FILTER",
// Textbox Field Filter
"addl_textbox":"TEXTBOX FILTER",
// Date Filter Start/End Range
"addl_date_start":"08/25/2022",
"addl_date_end":"08/27/2022",
// Date Filter Predefined Range
"addl_datetime_predefined":"this_week", // ["today", "yesterday", "this_week", "last_week", "this_month", "last_month", "not_set"]
"addl_checkbox":"True",
// Select Dropdown Field Filter
"addl_dropdown": [
"Articuno",
"Zapdos"
],
// Select Dropdown Field (Multi) Filter
"addl_dropdown_multi": [
"Eevee",
"Jolteon"
],
// Hyperlink Field Filter
"addl_hyperlink":"https://qbench.net",
// Object Relation Field Filter
"addl_obj_rel_user": [
"11"
],
// Object Relation Field (Multi) Filter
"addl_obj_rel_user_multi": [
"6"
],
"addl_obj_rel_contact_multi": [
"5"
],
// Any Field Type Not Set
"addl_field":"__{QB_FILTER_NO_VALUE_SET}__"
}
import json
import base64
json_params = json.dumps({
"addl_number":"12",
"addl_number_actionButton":"=", # Will find all items where "addl_numbers" equals 12
})
params_encoded = base64.b64encode(json_params.encode()).decode()
print(params_encoded) # eyJhZGRsX251bWJlciI6ICIxMiIsICJhZGRsX251bWJlcl9hY3Rpb25CdXR0b24iOiAiPSJ9
QBench API Endpoints
Click on the links below for more details for each Endpoint.
Customers
https://junctionconcepts.zendesk.com/hc/en-us/articles/360044676891-API-Customers
Contacts
https://junctionconcepts.zendesk.com/hc/en-us/articles/360044676971-API-Contacts
Patients
https://junctionconcepts.zendesk.com/hc/en-us/articles/360044229512-API-Patients-
Patient Contacts (Client)
https://junctionconcepts.zendesk.com/hc/en-us/articles/360044683931-API-Patient-Contacts-
Orders
https://junctionconcepts.zendesk.com/hc/en-us/articles/360044228952-API-Orders
Samples
https://junctionconcepts.zendesk.com/hc/en-us/articles/360044229612-API-Samples-
Tests
https://junctionconcepts.zendesk.com/hc/en-us/articles/360044229732-API-Test
Assays
https://junctionconcepts.zendesk.com/hc/en-us/articles/360044229772-API-Assay-
Panels
https://junctionconcepts.zendesk.com/hc/en-us/articles/360044677331-API-Panels-
Invoices
https://junctionconcepts.zendesk.com/hc/en-us/articles/360044229872-API-Invoices-
Attachments
https://junctionconcepts.zendesk.com/hc/en-us/articles/360044230052-API-Attachments-
Reports
https://junctionconcepts.zendesk.com/hc/en-us/articles/360044230172-API-Report
Batches
https://junctionconcepts.zendesk.com/hc/en-us/articles/360044230472-API-Batches
Updates
https://junctionconcepts.zendesk.com/hc/en-us/articles/360044678391-API-Updates
PrintDocs
https://junctionconcepts.zendesk.com/hc/en-us/articles/360044230392-API-PrintDocs
Protocol Step Worksheet
https://junctionconcepts.zendesk.com/hc/en-us/articles/360045293851-API-Protocol-Step-Worksheets
Payments
https://junctionconcepts.zendesk.com/hc/en-us/articles/360045293771-API-Payments-
Accessioning Types
https://junctionconcepts.zendesk.com/hc/en-us/articles/360045407591-API-Accessioning-Types-
Source
https://junctionconcepts.zendesk.com/hc/en-us/articles/360051077851-API-Source-
Activity Log
https://junctionconcepts.zendesk.com/hc/en-us/articles/4408710467085
Comments
0 comments
Please sign in to leave a comment.