API Developers Guide

Welcome to the API Developers Guide. This will cover most of the important concepts when using the API. Other details about the entities such as company, user, and notification filters can be found in the Portal user guide. https://ctci.atlassian.net/wiki/spaces/CTCIDOC/pages/340525116

This developer guide covers important points about using the API - Authentication, Error Handling, and such.

Endpoint

The server endpoint for requests is https://api.ctci.ai. There will be a dev sandbox version available soon.

Currently, all endpoints for requests use: /api/v1/<entity>.

The REST is our architectural standard for our API; it makes it easy to understand and easier to integrate into systems. In entity names, we are using the singular, not the plural. We use user and not users, as we think of an entity as being both singular and plural like a database table.

HTTP VERB

Operation

HTTP VERB

Operation

GET

Is to retrieve one or more entries.

Example:

GET https://api.ctci.ai/api/v1/user retrieves all users.
GET https://api.ctci.ai/api/v1/user/<id> retrieves the specific users.

POST

For the creation of an entity such as user, company, notification filter, notification group, notification delivery, processed, etc.

PUT

This is used to update entries.

Example:

PUT https://api.ctci.ai/api/v1/user/<id> would update the user with the <id>

DELETE

This is used to delete an entry.

Example:

DELETE https://api.ctci.ai/api/v1/user/<id> would delete the user with the <id>

Specification - Swagger / OAS

To view the Swagger API, https://swagger.ctci.ai/

To use the Swagger/OAS specification in your tools, then use this URL. https://raw.githubusercontent.com/vmcommunity/swagger-api/main/cewl_download_swagger.yaml

If you want to generate client code for this then, go to https://editor.swagger.io/, and use the File menu and use open URL, then use the swagger URL above. Postman works well for testing this API as well - the code snippets in this document were generated from Postman.

Authentication

For the API, you need to have credentials.

How to get your credentials:

  1. The preferred way: your company has been created by the CTCI team. If you want to start a trial, then send an email to sales@ctci.ai. Then register yourself as a user with an email address the same as the company email domain. You will then be able to log in and view the API tokens for your company. Depending on whether you have a CEWL subscription, is whether you see the full CEWL list or the restricted list. https://ctci.atlassian.net/wiki/spaces/CTCIDOC/pages/329416854

  2. Register as a user, confirm your address and then perform a login API request with your user name and password. your username and password. This will give you restricted access to the CEWL list - only the NSA Chinese State Actors list. https://ctci.atlassian.net/wiki/spaces/CTCIDOC/pages/340525116 We call this the JWT tokens for API.

Sending API Request

Authentication Tokens must be sent in every request. The examples below are to download the CEWL list.

Using API Tokens - the preferred way

With API Tokens, you need to set a header “x-api-key” with your API Token from the https://portal.ctci.ai. Examples are shown below. API Tokens cannot be used for interactive login using the CTCI Portal as they are only allowed for API.

Code Examples

Using Curl

1 2 curl --location --request GET 'https://api.ctci.ai/api/v1/cewl' \ --header 'x-api-key: <Put the API Token here>'

 

Using Python

1 2 3 4 5 6 7 8 9 10 11 12 import requests url = "https://api.ctci.ai/api/v1/cewl" payload={} headers = { 'x-api-key': '<Put the API Token here>' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text)

 

Using JavaScript

1 2 3 4 5 6 7 8 9 10 11 12 13 var myHeaders = new Headers(); myHeaders.append("x-api-key", "<Put the API Token here>"); var requestOptions = { method: 'GET', headers: myHeaders, redirect: 'follow' }; fetch("https://api.ctci.ai/api/v1/cewl", requestOptions) .then(response => response.text()) .then(result => console.log(result)) .catch(error => console.log('error', error));

Using JWT Tokens - the other way

This is using the access_token from a login/password authenticated response.

Firstly do a login to get the access_token.

 

Getting Access Token using Curl

1 2 3 curl --location --request POST 'http://127.0.0.1:5000/api/v1/login' \ --header 'Content-Type: application/json' \ --data-raw '{"username":"<your_username>","password":"<your_password"}'

 

Getting Access Token using Python

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import requests import json ACCESS_TOKEN_IDENTIFIER = "access_token" url = "http://127.0.0.1:5000/api/v1/login" payload = json.dumps({ "username": "<username>", "password": "<password>" }) headers = { 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) json_response = json.loads(response.text) if "ACCESS_TOKEN_IDENTIFIER" in json_response: access_token = json_response["ACCESS_TOKEN_IDENTIFIER"]

 

Then the response will have an access token, use this in the next requests.

1 2 3 4 5 6 7 8 { "access_token": "<access token>", "id": 6000, "firstname": "Joe", "lastname": "Bloggs", "nickname": "Joey", "roles": "admin" }

Code Examples using Access Token to call API

Using Curl

1 2 curl --location --request GET 'https://api.ctci.ai/api/v1/cewl' \ --header 'Authorization: Bearer <access token>'

Using Python

1 2 3 4 5 6 7 8 9 10 11 12 import requests url = "https://api.ctci.ai/api/v1/cewl" payload={} headers = { 'Authorization': 'Bearer <Put access_token here>' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text)

Using JavaScript

1 2 3 4 5 6 7 8 9 10 11 12 13 var myHeaders = new Headers(); myHeaders.append("Authorization", "Bearer <Put access_token here>"); var requestOptions = { method: 'GET', headers: myHeaders, redirect: 'follow' }; fetch("https://api.ctci.ai/api/v1/cewl", requestOptions) .then(response => response.text()) .then(result => console.log(result)) .catch(error => console.log('error', error));

Error Handling & Success Handling in the API

Where possible, we try to adhere to best practice standards for REST, and we try to adhere to good standards in error handling.

For HTTP Errors, we follow, where possible, the Problem Details for HTTP APIs: HTTP APIs (RFC 7807) https://datatracker.ietf.org/doc/html/rfc7807

Basically, this standard has some common values on errors, and then you can add your own specific error values.

We support:

Problem Details Fields RFC 7807

CTCI API

Problem Details Fields RFC 7807

CTCI API

status

Used - it’s the HTTP return status

title

The summary of the response

detail

More information about the response

type

Type of error

instance

This is the request path

parameter

any specific value that is sent in the request that may help to diagnose the error

data

Used only on success, this is the JSON of the response for the successful request.

Error Response

Example

1 2 3 4 5 6 {"status": 400, "title": "The user does not exist", "detail": "The user with user_id:999999 does not exist", "type": "Bad Request", "instance": "/api/v1/user/999999", "parameter": 999999}

Successful Response

The successful response uses a lot of fields as the error response, and it has an extra field, “data,” which carries the data about the request. Data is JSON.

A special note: if you try to update fields that you don’t have access to, it won’t update these fields, and if the request is properly formatted will return successfully. This was done as different fields that can be updated are dynamically determined by roles and such. This condition may change in the future and be an error.

Example

1 2 3 4 5 6 7 {"status": 200, "title": "List of users successful", "detail": "List of users successful", "type": "User", "instance": "/api/v1/user", "parameter": "", "data" : {"json response of the entities"}}