API Reference

The qlerk API is organized around REST. Our API has predictable resource-oriented URLs, accepts form-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs.


You can use the qlerk API in test mode, which doesn't affect your live data or interact with the banking networks. The API key you use to authenticate the request determines whether the request is live mode or test mode.


The qlerk API doesn't support bulk updates. You can work on only one object per request.

To optimize performance and reliability, qlerk has established rate limits and allocations for API endpoints.


Authentication

The qlerk API uses API keys to authenticate requests. You can get and manage your API keys with the help of your dedicated CRM.


Test mode secret keys have the prefix qk_test_ and live mode secret keys have the prefix qk_live_.


Your API keys carry many privileges, so be sure to keep them secure. Don't share your secret API keys in publicly accessible areas such as GitHub, client-side code, and so forth.


Authentication to the API is performed with HTTP Basic Auth. Provide your API key as the basic auth username value. You don't need to provide a password.


If you need to authenticate with bearer auth, for example, for a cross-origin request, use -H "Authorization: Bearer qk_test_4eC39HqLyjWDarjtT1zdp7dc" instead of -u qk_test_4eC39HqLyjWDarjtT1zdp7dc.


You must make all API calls over HTTPS. Calls that you make over plain HTTP will fail. API requests without authentication will also fail.


Errors

qlerk uses conventional HTTP response codes to indicate the success or failure of an API request. In general: Codes in the 2xx range indicate success. Codes in the 4xx range indicate an error that failed given the information provided (e.g., a required parameter was omitted, a payload failed, etc.). Codes in the 5xx range indicate an error with qlerk's servers (these are rare).


Our Client libraries raise exceptions for many reasons, such as a failed payload, invalid parameters, authentication errors, and network unavailability. We recommend writing code that gracefully handles all possible API exceptions.

Idempotent Requests

The API supports idempotency for safely retrying requests without accidentally performing the same operation twice. When creating or updating an object, use an idempotency key. Then, if a connection error occurs, you can safely repeat the request without risk of creating a second object or performing the update twice.


To perform an idempotent request, provide an additional Idempotency-Key: header to the request.


qlerk's idempotency works by saving the resulting status code and body of the first request made for any given idempotency key, regardless of whether it succeeded or failed. Subsequent requests with the same key return the same result, including 500 errors.


An idempotency key is a unique value generated by the client which the server uses to recognize subsequent retries of the same request. How you create unique keys is up to you, but we suggest using V4 UUIDs, or another random string with enough entropy to avoid collisions. Idempotency keys can be up to 255 characters long.


Keys are eligible to be removed from the system automatically after they're at least 24 hours old, and a new request is generated if a key is reused after the original has been pruned. The idempotency layer compares incoming parameters to those of the original request and errors unless they're the same to prevent accidental misuse.


Results are only saved if an API endpoint started executing. If incoming parameters failed validation, or the request conflicted with another that was executing concurrently, no idempotent result is saved because no API endpoint began execution. It is safe to retry these requests.


All POST requests accept idempotency keys. Sending idempotency keys in GET and DELETE requests has no effect and should be avoided, as these requests are idempotent by definition.

Metadata

Most updatable qlerk objects have a metadata parameter. You can use this parameter to attach arbitrary key-value data to these qlerk objects.


You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.


Metadata is useful for storing additional, structured information on an object. For example, you could store your user's corresponding unique identifier from your system on a qlerk customer object. By default, metadata isn't used for any operations by qlerk.


Don't store any sensitive information (bank account numbers, card details, and so on) in metadata.

Request IDs

Each API request has an associated request identifier. You can find this value in the response headers, under Request-Id.

Versioning

When backwards-incompatible changes are made to the API, a new, dated version is released.


All requests use your account API settings, unless you override the API version. Note that by default webhook events are structured according to your account API version, unless you set an API version during endpoint creation.


To set the API version on a specific request, send a version header.


You can reach out to your CRM to upgrade your API version. As a precaution, use API versioning to test a new API version before committing to an upgrade.

CORE RESOURCES

SETUP OF ATTRIBUTES, FUNDS, GUIDELINES AND DATA TRANSLATOR (RELAY)

Fund Attributes – Your internal attributes or international standard attributes

During the initial setup we need to setup your SEC master attributes in Qlerk to be able to setup guidelines in your internal representation of investment attributes. Alternatively, we can agree to monitor based on international standards in this case nothing needs to be done as they are already pre-setup.

Investment Fund – object representing an investment fund or portfolio

Investment Funds are setup directly within Qlerk – no API interaction is required

Guidelines – Monitoring rules applied to funds

Guidelines are setup and linked to funds directly within Qlerk – no API interaction is required

Relay – Translator fund holdings

The fund holdings are posted in Your data standard. We setup a translator to accordingly. At minimum we need Price, ISIN, Volume and Name.

MONITORING

POST /check-daily-holdings

POST to the check daily holdings resource will create a new check – one check per fund at a time can be run. Posting again for the same fund will restart the check.

The data standard is defined together and resembles your internal standard as close as possible to make your life easier. The only requirement from our side is to either include a fund id defined together or one derived from an open standard e.g. LEI

After posting you will get an immediate 200 Ok “Check Initiated” /400 Bad Request “Check Initiation Failed” (invalid structure, unknown fund) http response.

{

"creation_timestamp":"",

"update_timestamp":"",

"client_id":"",

"fund":{

"lei":"",

"name":"",

"legal_currency":""

},

"portfolio_valuation_date":"",

"shareclass":{

"isin":"",

"name":""

},

"holdings":[

{

"name":"",

"id":"",

"identification_type":"",

"quantity":"",

"unit_price_fund_currency":"",

"unit_price":"",

"unit_price_currency":"",

"attributes":[

{

"name":"ATTRIBUTE_1",

"value":"VALUE_1"

},

{

"name":"ATTRIBUTE_2",

"value":"VALUE_3"

}

]

},

{

"name":"",

"id":"",

"identification_type":"",

"quantity":"",

"unit_price_fund_currency":"",

"unit_price":"",

"unit_price_currency":"",

"attributes":[

{

"name":"ATTRIBUTE_1",

"value":"VALUE_1"

},

{

"name":"ATTRIBUTE_2",

"value":"VALUE_3"

}

]

}

]

}

Check Results Webhook

Webhook

• You will be informed about the result of the check via webhooks. It can be setup per fund, per guideline or for the entire portfolio. The recommended way is to setup per fund.

• Technically it is not required to make use of the webhooks alternatively we can inform the relevant people via email and the check results can be viewed directly in the Qlerk dashboard

• Investment Fund check structure:

{

"FundID":"GUID",

"FundName":"NAME",

"Date":"DATETIME",

"FundStatus":" OK, ISSUE_DETECTED",

"Guidelines":[

{

"GuidelineID":"GUID",

"GuidelineName":"NAME_1",

"GuidelineDescription":"Description_1",

"GuidelineResult":" OK, MISSING_DATA, MIN_FAILED, MAX_FAILED",

"GuidelineCheckDate":"DATETIME"

},

{

"GuidelineID":"GUID",

"GuidelineName":"NAME_2",

"GuidelineDescription":"Description_2",

"GuidelineResult":" OK, MISSING_DATA, MIN_FAILED, MAX_FAILED",

"GuidelineCheckDate":"DATETIME"

}

]

}