Getting Started

The User’s Guide topics can be read in any order, but if you are new to Factern we recommend the following walk-through for creating your first login, application and facts.

Creating a Login

Before you can make API calls against Factern, you must have a Factern Login and have created an application. This can be done by visiting the Factern Developer Portal:

https://portal.factern.com/#/login and clicking on Log in with OAuth.

You will be redirected to an auth0.com domain with a pop up widget to sign up for a new user account.

Screenshot

You must supply a valid email and password, or use a Google/Bitbucket account. Read and accept the terms of service, then click Sign Up. You may not use an email that has already been associated with another Factern login.

You will then be redirected back to Factern, logged in, and brought to the Applications view.

Screenshot

Creating an App

Now that you have created a login, you can now create an application. Click Create.

Screenshot

Supply a unique name and optionally a description. If you intend on using the Authentication Code OAuth flow you will also need to specify one or more redirect URIs. For this tutorial, though, we will assume you are using the Client Credentials OAuth flow, in which case, no redirect URIs are required.

Acquiring an Access Token

Every API call must supply an access token. In this tutorial, you will use the Client Credentials flow. In this flow, the application is assumed to be trusted by its users, so to acquire the token you need only supply the application's client ID and secret. You can find these two values in the application view when you first create the application.

Screenshot

From the client ID and secret you must generate the authorization request token. As with all our examples, we will be using the popular command-line tool curl for making API calls.

curl -X POST \
  https://factern-test.eu.auth0.com/oauth/token \
  -H 'Content-Type: application/json' \
  -d '{
  "client_id": "gIvTWlFmNNgz5xvhr2IR6o2Y1MzMwYe9",
  "client_secret": "FS_rNLrNiopDvAJpHl_z3YymceSMw56DyMlDIhSryTJ1Gqg3cPr5O7_Bksv7I64q",
  "audience": "https://api.factern.com",
  "grant_type": "client_credentials"
}'

Breaking down the request

Value Description
https://factern-test.eu.auth0.com The Factern OAuth server domain
/oauth/token The auth token request path
Content-Type: application/json Indicates payload is Json
"audience": "https://api.factern.com" The unique identifier of the target API
"grant_type": "client_credentials" Indicates we are using the Client Credentials OAuth flow

The response Access Token is to be supplied on all subsequent API calls.

{
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IlJqUXpORE01TWtRNFJqWkZNVEEwTnpFd01FVkRSREpHTVRSRk9UaEVPVU0xTURVeVJEZ3pPQSJ9.eyJodHRwczovL2FwaS5mYWN0ZXJuLmNvbS9hcHBfaWQiOiIwMDAwMDAwMDgzRjY1ODBBMjcwOTE4NUUwRkI4ODY5RDk4NDI3RTlGQjNFQUJENkMiLCJpc3MiOiJodHRwczovL2ZhY3Rlcm4tdGVzdC5ldS5hdXRoMC5jb20vIiwic3ViIjoiZ0l2VFdsRm1OTmd6NXh2aHIySVI2bzJZMU16TXdZZTlAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vYXBpLmZhY3Rlcm4uY29tIiwiaWF0IjoxNTI0NTA2MzgzLCJleHAiOjE1MjQ1OTI3ODMsImF6cCI6ImdJdlRXbEZtTk5nejV4dmhyMklSNm8yWTFNek13WWU5IiwiZ3R5IjoiY2xpZW50LWNyZWRlbnRpYWxzIn0.iT_4l1Iu10NZ7JWMtx1HpGErMjQJO0VDFfzJzjzLq-7Prux5vUr-mxnvg__kjhmYwwSxbCnMIFhlkacdqTEs07aItZ71a53KL-vYzR4rE3l-biuarP65LcAXIQpTJ3DGzE-y7DGEOZr1hMZFr3ZjkmG9GyN25u1EwB4O1PvfsWZ4h6ZBrmKzhvaTCDAZrWOGuOpVSNOp5ZsgYqx4Oey4pAv298aWe_UqKfEuLT7kk74AkSDUxK0pBmw-k17an_BbRDqO8D2_TT0S7okclEsb81yubjofYX9VcUJk75hJIUHGk2rc0J5qVLx-8i33gME1rMzjH8dKgQltkKeVJp_jlw",
    "expires_in": 86400,
    "token_type": "Bearer"
}

Note that the token has a time limit. In this case the token expiry is 3599 seconds or about one hour.

Creating Facts

Now that you have an authentication token, you can now make your first API call against Factern.

Every API call requires the id of the login on whose behalf the call is being made. Using Dev Portal, select the login profile:

Screenshot

The profile indicates the email associated with the login, as well as the Login Id:

Screenshot

With your first API call, you will be creating an entity called Alexander.

As with all our examples, we will be using the popular command-line tool curl for making API calls.

curl -XPOST 'https://api.factern.com/v2/createentity?user=000000002337758C219CA2CB0045D7E250CF1C55310A6811&operatingAs=000000002337758C219CA2CB0045D7E250CF1C55310A6811' \
    -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    -H 'Authorization: Bearer eyJraWQiOiJyc2ExIiwiYWxnIjoiUlMyNTYifQ.eyJhdWQiOiI4ZmY2ZjMxZi1hNjZiLTRlMGMtOGYyZC04N2MwMzc2ZTE1Y2IiLCJpc3MiOiJodHRwczpcL1wvc3NvLmZhY3Rlcm4uY29tXC9hdXRoXC8iLCJleHAiOjE0OTU1NDk5MDEsImlhdCI6MTQ5NTU0NjMwMSwianRpIjoiNDZjNGZkNDAtNjJlOS00M2NiLTlmZTgtYTI2ZTViN2RkYTNhIn0.F402AMctzVq7Kui2vthfDTCLfS4ImBqhbe8iRk7AJtLNkkj-52pwq2ySBSM3_QqizU-rz6UnJFat7qGXRro0eiYxk98ljcIEQ8iHFvgrosXpGJTrxG-OBLzYIissbEQjpysKQ7P_5UD7Cq-ZW5p8v29Ezs2kmZYV1sauSYZIAxN8cdphsIF2km6mjPm2MRVcvWbx49NGvkJ-HkAz_Bxc172cAzsLnD0gRZwVZgttzhZrTgEf21Nzho_EDuFUicpS02fTQvO53Hf9XPRnZtYHg4Q7k9XM8SIvj76x2FclxWhQZ-VyqXHIstMe2S6g-KugTDVTDGSuhALKBxwjaXY-Rw' \
    -d '
    {
        "name": "Alexander"
    }'

Breaking it down

Value Description
https://api.factern.com The Factern implementation domain
/v2/createentity The operation path name (in this case for creating an entity)
user=0000000023377... The login id associated with the call
operatingAs=0000000023377... The login id upon whose behalf the call is being made
Content-Type: application/json Indicates payload is Json
Accept: application/json Indicates response should be Json
Authorization: Bearer eyJraWQ... For supplying the authentication token
{"name": "Alexander" } Supplies the call payload (in this case, specifies the entity name)

We are going to supplying a couple facts for the Alexander entity: a full name and birthdate, where the birthdate will be further broken down by year, month and day. In Factern, every fact must be typed, and these types must exist prior to writing. Once a field type is created any number of facts can be written having that same type.

First we create the FullName field type.

curl -XPOST 'https://api.factern.com/v2/createfield?user=000000002337758C219CA2CB0045D7E250CF1C55310A6811&operatingAs=000000002337758C219CA2CB0045D7E250CF1C55310A6811' \
    -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    -H 'Authorization: Bearer eyJraWQiOiJyc2ExIiwiYWxnIjoiUlMyNTYifQ.eyJhdWQiOiI4ZmY2ZjMxZi1hNjZiLTRlMGMtOGYyZC04N2MwMzc2ZTE1Y2IiLCJpc3MiOiJodHRwczpcL1wvc3NvLmZhY3Rlcm4uY29tXC9hdXRoXC8iLCJleHAiOjE0OTU1NDk5MDEsImlhdCI6MTQ5NTU0NjMwMSwianRpIjoiNDZjNGZkNDAtNjJlOS00M2NiLTlmZTgtYTI2ZTViN2RkYTNhIn0.F402AMctzVq7Kui2vthfDTCLfS4ImBqhbe8iRk7AJtLNkkj-52pwq2ySBSM3_QqizU-rz6UnJFat7qGXRro0eiYxk98ljcIEQ8iHFvgrosXpGJTrxG-OBLzYIissbEQjpysKQ7P_5UD7Cq-ZW5p8v29Ezs2kmZYV1sauSYZIAxN8cdphsIF2km6mjPm2MRVcvWbx49NGvkJ-HkAz_Bxc172cAzsLnD0gRZwVZgttzhZrTgEf21Nzho_EDuFUicpS02fTQvO53Hf9XPRnZtYHg4Q7k9XM8SIvj76x2FclxWhQZ-VyqXHIstMe2S6g-KugTDVTDGSuhALKBxwjaXY-Rw' \
    -d '
    {
        "name":"FullName",
        "searchable": true,
        "uniqueByParent": true
    }'

Note that the field is marked as searchable and uniqueByParent.

A fact having a searchable field type can be discovered via the Factern search API.

A fact having a uniqueByParent field type indicates that there can only be one such fact for a given parent entity.

Now we create the BirthDate field type.

curl -XPOST 'https://api.factern.com/v2/createfield?user=000000002337758C219CA2CB0045D7E250CF1C55310A6811&operatingAs=000000002337758C219CA2CB0045D7E250CF1C55310A6811' \
    -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    -H 'Authorization: Bearer eyJraWQiOiJyc2ExIiwiYWxnIjoiUlMyNTYifQ.eyJhdWQiOiI4ZmY2ZjMxZi1hNjZiLTRlMGMtOGYyZC04N2MwMzc2ZTE1Y2IiLCJpc3MiOiJodHRwczpcL1wvc3NvLmZhY3Rlcm4uY29tXC9hdXRoXC8iLCJleHAiOjE0OTU1NDk5MDEsImlhdCI6MTQ5NTU0NjMwMSwianRpIjoiNDZjNGZkNDAtNjJlOS00M2NiLTlmZTgtYTI2ZTViN2RkYTNhIn0.F402AMctzVq7Kui2vthfDTCLfS4ImBqhbe8iRk7AJtLNkkj-52pwq2ySBSM3_QqizU-rz6UnJFat7qGXRro0eiYxk98ljcIEQ8iHFvgrosXpGJTrxG-OBLzYIissbEQjpysKQ7P_5UD7Cq-ZW5p8v29Ezs2kmZYV1sauSYZIAxN8cdphsIF2km6mjPm2MRVcvWbx49NGvkJ-HkAz_Bxc172cAzsLnD0gRZwVZgttzhZrTgEf21Nzho_EDuFUicpS02fTQvO53Hf9XPRnZtYHg4Q7k9XM8SIvj76x2FclxWhQZ-VyqXHIstMe2S6g-KugTDVTDGSuhALKBxwjaXY-Rw' \
    -d '
    {
       "name":"BirthDate",
       "branch": true,
       "uniqueByParent": true
}'

In this case, the field type is marked as branch. A fact having a branch field type can have sub-facts, in this case year, month and day facts.

Finally, we create the BirthYear, BirthMonth and BirthDay field types.

curl -XPOST 'https://api.factern.com/v2/createfield?user=000000002337758C219CA2CB0045D7E250CF1C55310A6811&operatingAs=000000002337758C219CA2CB0045D7E250CF1C55310A6811' \
    -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    -H 'Authorization: Bearer eyJraWQiOiJyc2ExIiwiYWxnIjoiUlMyNTYifQ.eyJhdWQiOiI4ZmY2ZjMxZi1hNjZiLTRlMGMtOGYyZC04N2MwMzc2ZTE1Y2IiLCJpc3MiOiJodHRwczpcL1wvc3NvLmZhY3Rlcm4uY29tXC9hdXRoXC8iLCJleHAiOjE0OTU1NDk5MDEsImlhdCI6MTQ5NTU0NjMwMSwianRpIjoiNDZjNGZkNDAtNjJlOS00M2NiLTlmZTgtYTI2ZTViN2RkYTNhIn0.F402AMctzVq7Kui2vthfDTCLfS4ImBqhbe8iRk7AJtLNkkj-52pwq2ySBSM3_QqizU-rz6UnJFat7qGXRro0eiYxk98ljcIEQ8iHFvgrosXpGJTrxG-OBLzYIissbEQjpysKQ7P_5UD7Cq-ZW5p8v29Ezs2kmZYV1sauSYZIAxN8cdphsIF2km6mjPm2MRVcvWbx49NGvkJ-HkAz_Bxc172cAzsLnD0gRZwVZgttzhZrTgEf21Nzho_EDuFUicpS02fTQvO53Hf9XPRnZtYHg4Q7k9XM8SIvj76x2FclxWhQZ-VyqXHIstMe2S6g-KugTDVTDGSuhALKBxwjaXY-Rw' \
    -d '
    {
        "name":"BirthYear",
        "uniqueByParent": true
    }'
curl -XPOST 'https://api.factern.com/v2/createfield?user=000000002337758C219CA2CB0045D7E250CF1C55310A6811&operatingAs=000000002337758C219CA2CB0045D7E250CF1C55310A6811' \
    -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    -H 'Authorization: Bearer eyJraWQiOiJyc2ExIiwiYWxnIjoiUlMyNTYifQ.eyJhdWQiOiI4ZmY2ZjMxZi1hNjZiLTRlMGMtOGYyZC04N2MwMzc2ZTE1Y2IiLCJpc3MiOiJodHRwczpcL1wvc3NvLmZhY3Rlcm4uY29tXC9hdXRoXC8iLCJleHAiOjE0OTU1NDk5MDEsImlhdCI6MTQ5NTU0NjMwMSwianRpIjoiNDZjNGZkNDAtNjJlOS00M2NiLTlmZTgtYTI2ZTViN2RkYTNhIn0.F402AMctzVq7Kui2vthfDTCLfS4ImBqhbe8iRk7AJtLNkkj-52pwq2ySBSM3_QqizU-rz6UnJFat7qGXRro0eiYxk98ljcIEQ8iHFvgrosXpGJTrxG-OBLzYIissbEQjpysKQ7P_5UD7Cq-ZW5p8v29Ezs2kmZYV1sauSYZIAxN8cdphsIF2km6mjPm2MRVcvWbx49NGvkJ-HkAz_Bxc172cAzsLnD0gRZwVZgttzhZrTgEf21Nzho_EDuFUicpS02fTQvO53Hf9XPRnZtYHg4Q7k9XM8SIvj76x2FclxWhQZ-VyqXHIstMe2S6g-KugTDVTDGSuhALKBxwjaXY-Rw' \
    -d '
    {
        "name":"BirthMonth",
        "uniqueByParent": true
    }'
curl -XPOST 'https://api.factern.com/v2/createfield?user=000000002337758C219CA2CB0045D7E250CF1C55310A6811&operatingAs=000000002337758C219CA2CB0045D7E250CF1C55310A6811' \
    -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    -H 'Authorization: Bearer eyJraWQiOiJyc2ExIiwiYWxnIjoiUlMyNTYifQ.eyJhdWQiOiI4ZmY2ZjMxZi1hNjZiLTRlMGMtOGYyZC04N2MwMzc2ZTE1Y2IiLCJpc3MiOiJodHRwczpcL1wvc3NvLmZhY3Rlcm4uY29tXC9hdXRoXC8iLCJleHAiOjE0OTU1NDk5MDEsImlhdCI6MTQ5NTU0NjMwMSwianRpIjoiNDZjNGZkNDAtNjJlOS00M2NiLTlmZTgtYTI2ZTViN2RkYTNhIn0.F402AMctzVq7Kui2vthfDTCLfS4ImBqhbe8iRk7AJtLNkkj-52pwq2ySBSM3_QqizU-rz6UnJFat7qGXRro0eiYxk98ljcIEQ8iHFvgrosXpGJTrxG-OBLzYIissbEQjpysKQ7P_5UD7Cq-ZW5p8v29Ezs2kmZYV1sauSYZIAxN8cdphsIF2km6mjPm2MRVcvWbx49NGvkJ-HkAz_Bxc172cAzsLnD0gRZwVZgttzhZrTgEf21Nzho_EDuFUicpS02fTQvO53Hf9XPRnZtYHg4Q7k9XM8SIvj76x2FclxWhQZ-VyqXHIstMe2S6g-KugTDVTDGSuhALKBxwjaXY-Rw' \
    -d '
    {
        "name":"BirthDay",
        "uniqueByParent": true
    }'

Now that you have done the leg work of creating the field types we can create the facts for the Alexander entity.

curl -XPOST 'https://api.factern.com/v2/write?user=000000002337758C219CA2CB0045D7E250CF1C55310A6811&operatingAs=000000002337758C219CA2CB0045D7E250CF1C55310A6811' \
    -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    -H 'Authorization: Bearer eyJraWQiOiJyc2ExIiwiYWxnIjoiUlMyNTYifQ.eyJhdWQiOiI4ZmY2ZjMxZi1hNjZiLTRlMGMtOGYyZC04N2MwMzc2ZTE1Y2IiLCJpc3MiOiJodHRwczpcL1wvc3NvLmZhY3Rlcm4uY29tXC9hdXRoXC8iLCJleHAiOjE0OTU1NDk5MDEsImlhdCI6MTQ5NTU0NjMwMSwianRpIjoiNDZjNGZkNDAtNjJlOS00M2NiLTlmZTgtYTI2ZTViN2RkYTNhIn0.F402AMctzVq7Kui2vthfDTCLfS4ImBqhbe8iRk7AJtLNkkj-52pwq2ySBSM3_QqizU-rz6UnJFat7qGXRro0eiYxk98ljcIEQ8iHFvgrosXpGJTrxG-OBLzYIissbEQjpysKQ7P_5UD7Cq-ZW5p8v29Ezs2kmZYV1sauSYZIAxN8cdphsIF2km6mjPm2MRVcvWbx49NGvkJ-HkAz_Bxc172cAzsLnD0gRZwVZgttzhZrTgEf21Nzho_EDuFUicpS02fTQvO53Hf9XPRnZtYHg4Q7k9XM8SIvj76x2FclxWhQZ-VyqXHIstMe2S6g-KugTDVTDGSuhALKBxwjaXY-Rw' \
    -d '
    {
        "nodeId":"frn:entity::Alexander",
        "document": [
            {":FullName": "Alexander Great"},
            {":BirthDate": [
                {":BirthYear": 2000},
                {":BirthMonth": "March"},
                {":BirthDay": 1}
            ]}
        ]
    }'

Note the request payload includes the target of the facts, specified as frn:entity::Alexander. This is the FRN of the Alexander entity. As well, the payload includes the facts, themselves:

[
    {":FullName": "Alexander Great"},
    {":BirthDate": [
        {":BirthYear": 2000},
        {":BirthMonth": "March"},
        {":BirthDay": 1}
    ]}
]

The field types of the fact values are specified using brief FRNs. For example, :FullName refers to the FullName field type you created earlier.

The facts you have written about Alexander can be read back.

curl -XPOST 'https://api.factern.com/v2/read?user=000000002337758C219CA2CB0045D7E250CF1C55310A6811&operatingAs=000000002337758C219CA2CB0045D7E250CF1C55310A6811' \
    -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    -H 'Authorization: Bearer eyJraWQiOiJyc2ExIiwiYWxnIjoiUlMyNTYifQ.eyJhdWQiOiI4ZmY2ZjMxZi1hNjZiLTRlMGMtOGYyZC04N2MwMzc2ZTE1Y2IiLCJpc3MiOiJodHRwczpcL1wvc3NvLmZhY3Rlcm4uY29tXC9hdXRoXC8iLCJleHAiOjE0OTU1NDk5MDEsImlhdCI6MTQ5NTU0NjMwMSwianRpIjoiNDZjNGZkNDAtNjJlOS00M2NiLTlmZTgtYTI2ZTViN2RkYTNhIn0.F402AMctzVq7Kui2vthfDTCLfS4ImBqhbe8iRk7AJtLNkkj-52pwq2ySBSM3_QqizU-rz6UnJFat7qGXRro0eiYxk98ljcIEQ8iHFvgrosXpGJTrxG-OBLzYIissbEQjpysKQ7P_5UD7Cq-ZW5p8v29Ezs2kmZYV1sauSYZIAxN8cdphsIF2km6mjPm2MRVcvWbx49NGvkJ-HkAz_Bxc172cAzsLnD0gRZwVZgttzhZrTgEf21Nzho_EDuFUicpS02fTQvO53Hf9XPRnZtYHg4Q7k9XM8SIvj76x2FclxWhQZ-VyqXHIstMe2S6g-KugTDVTDGSuhALKBxwjaXY-Rw' \
    -d '
    {
        "nodeId":"frn:entity::Alexander",
        "template": [
            ":FullName",
            {":BirthDate": [
                ":BirthYear",
                ":BirthMonth",
                ":BirthDay"
            ]}
        ]
    }'

As with the write payload, the read request payload indicates the target of the read, using the FRN of the Alexander entity. The template part of the payload indicates the field types of the facts you are interested in reading about Alexander.

Further Reading

Now that you have created your first facts, you can explore other facets of Factern.

A general guide for furthering your exploration is given below:

Understanding API Calls

Facts and Data Basics

Advanced Facts

Permissions