# Authentication ## API Key This is the easiest way to authenticate, simply add the `x-api-key` header with your API Key to your requests. ## API Key + JWT Signing Using JWT adds a degree of complexity but it is strongly recommended to use when you are going to call this API in client-side applications.\ \ The JWT Token offers an additional layer of security since it will remain in your source code and will not be sent with requests.\ \ You will still need to add the `x-api-key` to your requests and this time also `x-signature`. It can be generated as follows: {% tabs %} {% tab title="Go" %} ```go import ( "github.com/golang-jwt/jwt/v5" ) func GenerateSignature(apiKey, jwtKey string) (string, error) { claims := jwt.MapClaims{} claims["key"] = apiKey claims["exp"] = time.Now().Add(time.Second * 15).Unix() // this prevents replay attacks token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) tokenString, err := token.SignedString([]byte(jwtKey)) if err != nil { return "", err } return tokenString, nil } ``` {% endtab %} {% tab title="JavaScript" %} ```javascript const jwt = require('jsonwebtoken'); function generateSignature(apiKey, jwtKey) { const claims = { key: apiKey, // Set expiration to 15 seconds from now to prevent replay attacks exp: Math.floor(Date.now() / 1000) + 15, }; try { const tokenString = jwt.sign(claims, jwtKey, { algorithm: 'HS256' }); return tokenString; } catch (err) { throw err; } } ``` {% endtab %} {% tab title="Python" %} The following function requires `PyJWT` to be installed. ``` pip install PyJWT ``` ```python import jwt import time def generate_signature(api_key, jwt_key): claims = { 'key': api_key, # Set expiration to 15 seconds from now to prevent replay attacks 'exp': int(time.time()) + 15, } try: token_string = jwt.encode(claims, jwt_key, algorithm='HS256') return token_string except Exception as error: raise error ``` {% endtab %} {% endtabs %} ### Organizations Organization owners can authenticate API requests on behalf of their users by using their App Key and App Secret. These credentials are available in your organization dashboard. Add the following headers to your requests: | Header | Description | | ----------------- | -------------------------------------------------- | | `x-api-key` | The user's API Key | | `x-app-key` | Your organization's App Key | | `x-app-signature` | A signed JWT token generated using your App Secret | The signature is generated the same way as the standard JWT signing method: {% tabs %} {% tab title="Go" %} ```go import ( "time" "github.com/golang-jwt/jwt/v5" ) func generateSignature(appKey string, appSecret []byte) (string, error) { claims := jwt.MapClaims{ "key": appKey, "exp": time.Now().Add(time.Minute).Unix(), } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) return token.SignedString(appSecret) } ``` {% endtab %} {% tab title="JavaScript" %} ```javascript const jwt = require('jsonwebtoken'); function generateSignature(appKey, appSecret) { const claims = { key: appKey, exp: Math.floor(Date.now() / 1000) + 60, }; return jwt.sign(claims, appSecret, { algorithm: 'HS256' }); } ``` {% endtab %} {% tab title="Python" %} ```python import jwt import time def generate_signature(app_key: str, app_secret: str) -> str: claims = { 'key': app_key, 'exp': int(time.time()) + 60, } return jwt.encode(claims, app_secret, algorithm='HS256') ``` {% endtab %} {% endtabs %} {% hint style="info" %} The `x-app-key` and `x-app-signature` headers are only for organization owners. Individual users should continue using the standard `x-api-key` authentication. {% endhint %}