Authentication

XFX APIs use the OAuth 2.0 Client Credentials flow. This flow is designed for server-to-server integrations and does not involve user interaction.

At a high level:

  1. Obtain an access token using your client credentials
  2. Include the access token in all API requests

Prerequisites

Before authenticating, ensure you have:

  • An XFX Client ID
  • An XFX Client Secret
  • The correct API base URL for your environment

⚠️

We recommend storing these values as environment variables and never hardcoding them.


Step 1: Obtain an Access Token

Request an access token by calling the OAuth token endpoint.

Endpoint

POST https://dev-er8o7vv4aka08m70.us.auth0.com/oauth/token

Request

curl --request POST \
  --url 'https://dev-er8o7vv4aka08m70.us.auth0.com/oauth/token' \
  --header 'Content-Type: application/json' \
  --data '{
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "audience": "https://api.xfx.io/trading",
    "grant_type": "client_credentials"
  }'

Response

{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 86400
}

Response fields

FieldDescription
access_tokenToken used to authenticate API requests
token_typeAlways Bearer
expires_inToken lifetime in seconds (24 hours)

Step 2: Use the Access Token

Include the access token in the Authorization header for all API requests.

Authorization: Bearer YOUR_ACCESS_TOKEN

🚧

Requests without a valid token will be rejected with a 401 Unauthorized response.


Token Management Best Practices

Do

  • Cache tokens and reuse them until close to expiration
  • Refresh tokens automatically before they expire
  • Store credentials securely using environment variables or a secrets manager

Don't

  • Request a new token for every API call
  • Commit tokens or secrets to code repositories

Example: Token Caching and Refresh (JavaScript)

class XFXAuthClient {
  constructor(clientId, clientSecret, auth0Domain) {
    this.clientId = clientId;
    this.clientSecret = clientSecret;
    this.auth0Domain = auth0Domain;
    this.token = null;
    this.tokenExpiry = null;
  }

  async getAccessToken() {
    // Return cached token if still valid
    if (this.token && this.tokenExpiry && Date.now() < this.tokenExpiry) {
      return this.token;
    }

    // Request new token
    const response = await fetch(
      `https://${this.auth0Domain}/oauth/token`,
      {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          client_id: this.clientId,
          client_secret: this.clientSecret,
          audience: 'https://api.xfx.io/trading',
          grant_type: 'client_credentials'
        })
      }
    );

    const data = await response.json();

    // Cache token with 5-minute buffer before expiration
    this.token = data.access_token;
    this.tokenExpiry = Date.now() + ((data.expires_in - 300) * 1000);

    return this.token;
  }
}

💡

The 5-minute buffer (expires_in - 300) ensures the token is refreshed before it actually expires, avoiding failed requests during the transition.