Authenticating with Public/Private Keypair
Public/Private Keypair authentication is recommended when using the Link API for production use cases. While it requires some additional setup, this method is the most secure and easy way to use Link in the long term. For testing and development, individual users should check out the authentication quickstart guide.
Keypair Setup
Generate an RSA Keypair
In this guide, we will use the openssl
library, which is available on Unix systems (which includes Macs).
First, open a terminal and generate a 2048-bit private key:
openssl genrsa -out private.pem 2048
Next, extract the public key:
openssl rsa -in private.pem -outform PEM -pubout -out public.pem
Send Kensho Your Public Key
Email support@kensho.com with your PEM encoded public key as an attachment. We will respond with your Client ID
.
You will need this ID in the following step. While typical response times are very quick, please allow up to
three business days for us to process your request.
Important: Do not send us your private key! While your public key and Client ID
are not secret, your private key
should not be shared outside your organization.
Use Your Private Key and Client ID to Generate an Acess Token
Most languages have JWT (JSON Web Token) libraries. In this example, we make use of PyJWT, a JWT library for Python.
We provide a get_access_token_from_key
helper function that can be used.
import jwtimport requestsimport timedef get_access_token_from_key(client_id):PRIVATE_KEY_PATH = "private.pem" # the location of your generated private key filewith open(PRIVATE_KEY_PATH, "rb") as f:private_key = f.read()iat = int(time.time())encoded = jwt.encode({"aud": "https://kensho.okta.com/oauth2/default/v1/token","exp": iat + (30 * 60), # expire in 30 minutes"iat": iat,"sub": client_id,"iss": client_id,},private_key,algorithm="RS256",)response = requests.post("https://kensho.okta.com/oauth2/default/v1/token",headers={"Content-Type": "application/x-www-form-urlencoded","Accept": "application/json",},data={"scope": "kensho:app:link-model-server","grant_type": "client_credentials","client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer","client_assertion": encoded,})return response.json()["access_token"]CLIENT_ID = "" # paste your Client ID sent to you by Kensho inside the quotation marksACCESS_TOKEN = get_access_token_from_key(CLIENT_ID)
Note that Content-Type
is specified as application/x-www-form-urlencoded
. When you call requests.post()
in python,
data
dictionary will automatically be converted into a string formatted like this:
client_assertion=xxxxxxx&scope=kensho:app:link-model-server&grant_type=client_credentials&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
If you are using another programming language, you need to make sure you send data
in the format specified above, rather than sending in JSON.
Verify Token
To test out your new Access Token
, run
curl -H "Authorization: Bearer <your token>" https://link-streaming.kensho.com/me
If you get a response with your client ID, you're in the money! Head over to the REST API Guide to link your records to S&P records.
Production Use
Using your Public/Private Keypair allows you to always generate a fresh Access Token
. This token expires every hour,
on the hour, so you will need to regenerate it during a long-running application. We provide an example in Python below.
Note that this snippet uses the get_access_token_from_key
defined above. For more details on using the Link API,
check out the REST API Guide.
The code below defines a LinkClient
class that can be used to make requests to the Link on-demand endpoint.
This client will update the access token when needed, using public/private keypair authentication.
You will need to paste your Client ID (emailed to you by our support@kensho.com team in the steps above) in the field
CLIENT_ID
. Below the LinkClient
definition, the client is used to make linking requests for two companies,
"S&P Global Inc." and "kensho".
import jsonimport requestsimport timeimport osCLIENT_ID = "" # paste your Client ID sent to you by Kensho inside the quotation marksclass LinkClient:"""A class to call the Link API that automatically refreshes tokens when needed."""def __init__(self, client_id):self.client_id = client_iddef update_access_token(self):self.access_token = get_access_token_from_key(self.client_id)def call_api(self, verb, *args, headers={}, **kwargs):"""Call Link API, refreshing access token as needed."""if not hasattr(self, "access_token"):self.update_access_token()def call_with_updated_headers():nonlocal methodheaders["Authorization"] = f"Bearer {self.access_token}"return method(*args, headers=headers, **kwargs)method = getattr(requests, verb)response = call_with_updated_headers()if response.status_code == 401:self.update_access_token()response = call_with_updated_headers()return responsedef make_link_request(self, knowledge_base, data):"""Make a POST call to Link On-Demand Endpoint."""response = self.call_api("post",f"https://link-streaming.kensho.com/api/ondemand/v0/companies/{knowledge_base}/generic",data=json.dumps(data),headers={"Content-Type": "application/json"})return response.json()# knowledge base to link to ("capiq" or "mi")knowledge_base = "capiq"# link request datadata = {"records": [{"uid": "1","name": "S&P Global Inc.","aliases": ["S&P", "SPGI"],"country_iso3": "USA","address": "55 Water Street","state": "New York","city": "New York","zipcode": "10041","year_founded": 1917,"url": "https://www.spglobal.com/","phone_number": "718-123-4567"},{"uid": "2","name": "kensho"}],"num_top_records": 2,"include_response_fields": ["knowledge_base_name"],}# create a link clientlink_client = LinkClient(CLIENT_ID)# submit request to on-demand endpointlinked_results = link_client.make_link_request(knowledge_base, data)