Authentication

You'll need to authenticate your requests to access any of the endpoints in the Finite State API. In this guide, we'll look at how authentication works.

Getting Access

Contact your Finite State representative to get a CLIENT_ID, CLIENT_SECRET, and ORGANIZATION_CONTEXT for use with the API.

NOTE: This will be built into the platform in the future so you can manage your own API keys.

Make a request to get a Bearer Token

Using your CLIENT_ID and CLIENT_SECRET, query the https://platform.finitestate.io/api/v1/auth/token endpoint to retrieve a token. This token expires after 24 hours, so your code will need to request a new token every day.

Using Python

Create a .secrets file

CLIENT_ID=<YOUR CLIENT ID>
CLIENT_SECRET=<YOUR CLIENT SECRET>
ORGANIZATION_CONTEXT=<YOUR ORGANIZATION CONTEXT>

Install Python libraries

Install Python libraries

pip install requests
pip install python-dotenv
import requests
import json
import os
from dotenv import load_dotenv

# Load environment variables from the file
load_dotenv('.secrets', override=True)

# Access the environment variables
client_id = os.getenv('CLIENT_ID')
client_secret = os.getenv('CLIENT_SECRET')

url = "https://platform.finitestate.io/api/v1/auth/token"
audience = "https://platform.finitestate.io/api/v1/graphql"

payload = {
    "client_id": client_id,
    "client_secret": client_secret,
    "audience": audience,
    "grant_type": "client_credentials"
}

headers = {
    'content-type': "application/json"
}

response = requests.post(url, data=json.dumps(payload), headers=headers)

# The response contains the access token
print(response.json())

# Example response
{'access_token': 'eyJhbGc...A LOT OF CHARACTERS HERE...PGoXv5g', 'expires_in': 86400, 'token_type': 'Bearer'}

Using Bash

Create a .secretsrc file

.secretsrc file contents

export CLIENT_ID=<YOUR CLIENT ID>
export CLIENT_SECRET=<YOUR CLIENT SECRET>

Source the .secretsrc file

Source the .secretsrc file

source .secretsrc

Getting the bearer token in Bash

curl --request POST --url https://platform.finitestate.io/api/v1/auth/token
  --header "content-type: application/json" \
  --data "{\"client_id\":\""$CLIENT_ID"\",\"client_secret\":\""$CLIENT_SECRET"\",\"audience\":\"https://platform.finitestate.io/api/v1/graphql\",\"grant_type\":\"client_credentials\"}"

# Example response
{'access_token': 'eyJhbGc...A LOT OF CHARACTERS HERE...PGoXv5g', 'expires_in': 86400, 'token_type': 'Bearer'}

Using the Bearer Token

All requests to the Finite State API must include a Authorization header with the value Bearer <token> in addition to an Organization-Context. The Organization-Context should have been provided to you by your Finite State representative, and looks like xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

For example:

Example Header

{
  'Content-Type': 'application/json',
  'Authorization': 'Bearer <YOUR TOKEN>'
  'Organization-Context': '<YOUR ORG CONTEXT>'
}
import requests
import json
import os
from dotenv import load_dotenv

# Load environment variables from the file
load_dotenv('.secrets', override=True)

# Access the environment variables
client_id = os.getenv('CLIENT_ID')
client_secret = os.getenv('CLIENT_SECRET')
organization_context = os.getenv('ORGANIZATION_CONTEXT')

token_url = "https://platform.finitestate.io/api/v1/auth/token"
audience = "https://platform.finitestate.io/api/v1/graphql"
api_url = 'https://platform.finitestate.io/api/v1/graphql'


def get_auth_token():
    payload = {
        "client_id": client_id,
        "client_secret": client_secret,
        "audience": audience,
        "grant_type": "client_credentials"
    }

    headers = {
        'content-type': "application/json"
    }

    response = requests.post(token_url, data=json.dumps(payload), headers=headers)
    if response.status_code == 200:
        return response.json()['access_token']
    else:
        print('Error:', response.status_code)
        print(response.text)
        auth_token = None

    return auth_token


# Send a GraphQL query to the API
def send_graphql_query(api_url, query, token):
    headers = {
        'Content-Type': 'application/json',
        'Authorization': f'Bearer {token}',
        'Organization-Context': organization_context
    }
    data = {
        'query': query
    }

    response = requests.post(api_url, headers=headers, json=data)

    if response.status_code == 200:
        return response.json()
    else:
        print('Error:', response.status_code)
        print(response.text)
        return None


# Example usage
auth_token = get_auth_token()

graphql_query = '''
query AllProducts {
    allProducts {
        id
        name
    }
}
'''

response_data = send_graphql_query(api_url, graphql_query, auth_token)

if response_data:
    print(response_data)

FAQ

Q: What happens if my token expires?

A: If you receive an HTTP 401 it may contain the following:

{
  "message": "UnauthorizedError: jwt expired\n    at new UnauthorizedError (/usr/app/node_modules/express-jwt/dist/errors/UnauthorizedError.js:22:28)\n    at /usr/app/node_modules/express-jwt/dist/index.js:139:38\n    at step (/usr/app/node_modules/express-jwt/dist/index.js:33:23)\n    at Object.next (/usr/app/node_modules/express-jwt/dist/index.js:14:53)\n    at fulfilled (/usr/app/node_modules/express-jwt/dist/index.js:5:58)"
}

This means your token has expired and you need to generate a new one. See Make a request to get a Bearer Token for more information.