Skip to main content
The Authorization Code flow uses a client_secret to authenticate when exchanging the authorization code for tokens. Use this flow when your application runs on a server and can securely store credentials — for example, Node.js, Python, or PHP backends.

Prerequisites

Before you implement this flow, ensure you have:
  • OAuth2 client credentialsRegister your app in Client Center to get client_id and client_secret
  • Redirect URI — Must be pre-registered in Client Center and must exactly match (protocol, host, path, trailing slashes)
  • Server-side runtime — Node.js 18+, Python 3.8+, or equivalent for your language
  • Session or secure storage — To persist state between redirect and callback, and to store tokens after exchange
The client_secret is shown only once when you create the client. Copy it immediately and store it in environment variables or a secrets manager. If lost, regenerate it in Client Center.

Step 1: Build the authorization URL and redirect

Redirect the user to the Aries authorization endpoint. They will see a login and consent screen where they can approve or deny the requested permissions. Endpoint: https://app.aries.com/oauth2/authorize Required query parameters:
ParameterDescription
response_typeMust be code
client_idYour OAuth2 client ID
redirect_uriMust exactly match a registered URI
scopeSpace-separated scopes (e.g., account:information order:execution)
stateCryptographically random string for CSRF protection — verify on callback
const crypto = require('crypto');

// Generate state and save to session for callback verification
const state = crypto.randomBytes(32).toString('hex');
req.session.oauth_state = state;

const params = new URLSearchParams({
  response_type: 'code',
  client_id: process.env.ARIES_CLIENT_ID,
  redirect_uri: process.env.ARIES_REDIRECT_URI,
  scope: 'account:information order:execution market:information',
  state: state,
});

const authUrl = `https://app.aries.com/oauth2/authorize?${params}`;
res.redirect(authUrl);
Always generate a new, cryptographically random state for each authorization request and verify it when the user returns. This prevents CSRF attacks.

Step 2: Handle the callback

After the user approves, Aries redirects to your redirect_uri with an authorization code and the state you provided. If the user denies access, you receive error parameters instead. Success callback:
https://yourapp.com/oauth/callback?code=AUTHORIZATION_CODE&state=YOUR_STATE
Error callback (user denied or error):
https://yourapp.com/oauth/callback?error=access_denied&error_description=User+denied+access&state=YOUR_STATE
ParameterDescription
codeAuthorization code — valid for 10 minutes, single-use. Exchange immediately.
stateMust match the value you sent. Verify before proceeding.
app.get('/oauth/callback', async (req, res) => {
  // Verify state to prevent CSRF
  if (req.query.state !== req.session.oauth_state) {
    return res.status(400).send('Invalid state parameter');
  }

  // Handle user denial or other errors
  if (req.query.error) {
    return res.status(400).send(`Authorization error: ${req.query.error}`);
  }

  const authCode = req.query.code;
  if (!authCode) {
    return res.status(400).send('No authorization code received');
  }

  try {
    const tokens = await exchangeCodeForToken(authCode);
    req.session.access_token = tokens.access_token;
    req.session.refresh_token = tokens.refresh_token;
    req.session.token_expires_at = Date.now() + tokens.expires_in * 1000;
    res.redirect('/dashboard');
  } catch (err) {
    res.status(500).send('Token exchange failed');
  }
});

Step 3: Exchange the code for tokens

Send the authorization code to the token endpoint to receive an access token and refresh token. The code is single-use — exchange it immediately after receiving it. Endpoint: POST https://api.aries.com/v1/oauth2/token Request body:
FieldRequiredDescription
client_idYesYour OAuth2 client ID
client_secretYesYour OAuth2 client secret
grant_typeYescode
codeYesThe authorization code from the callback
redirect_uriYesMust match the redirect URI used in Step 1
curl -X POST 'https://api.aries.com/v1/oauth2/token' \
  -H 'Content-Type: application/json' \
  -d '{
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "grant_type": "code",
    "code": "AUTHORIZATION_CODE",
    "redirect_uri": "YOUR_REDIRECT_URI"
  }'
Response:
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "eyJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAifQ...",
  "scope": "account:information order:execution market:information"
}
Store the access_token, refresh_token, and expires_in (use it to compute expiry time). Replace your stored refresh_token if a new one is returned.

Step 4: Make authenticated API requests

Include the access token in the Authorization header for every API request.
Authorization: Bearer YOUR_ACCESS_TOKEN
curl -X GET 'https://api.aries.com/v1/users/me/accounts' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN'

Step 5: Refresh the access token

Access tokens expire after expires_in seconds (typically 1 hour). Use the refresh token to obtain a new access token without requiring the user to log in again. Refresh proactively before expiry. Endpoint: POST https://api.aries.com/v1/oauth2/token Request body:
FieldRequiredDescription
client_idYesYour OAuth2 client ID
client_secretYesYour OAuth2 client secret
grant_typeYesrefresh_token
refresh_tokenYesThe refresh token from the initial exchange
redirect_uriYesMust match the redirect URI used in the original flow
curl -X POST 'https://api.aries.com/v1/oauth2/token' \
  -H 'Content-Type: application/json' \
  -d '{
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "grant_type": "refresh_token",
    "refresh_token": "YOUR_REFRESH_TOKEN",
    "redirect_uri": "YOUR_REDIRECT_URI"
  }'
The response format is the same as the initial token exchange. If a new refresh_token is returned, persist it — it replaces the previous one.

Complete example (Node.js)

Here is a minimal Express.js server demonstrating the full flow:
Node.js
const express = require('express');
const crypto = require('crypto');
const session = require('express-session');

const app = express();
app.use(session({ secret: 'your-session-secret', resave: false, saveUninitialized: false }));

// Step 1: Redirect to Aries
app.get('/login', (req, res) => {
  const state = crypto.randomBytes(32).toString('hex');
  req.session.oauth_state = state;

  const params = new URLSearchParams({
    response_type: 'code',
    client_id: process.env.ARIES_CLIENT_ID,
    redirect_uri: process.env.ARIES_REDIRECT_URI,
    scope: 'user:information account:information',
    state,
  });

  res.redirect(`https://app.aries.com/oauth2/authorize?${params}`);
});

// Step 2 & 3: Callback and token exchange
app.get('/oauth/callback', async (req, res) => {
  if (req.query.state !== req.session.oauth_state) {
    return res.status(400).send('Invalid state');
  }
  if (req.query.error) {
    return res.status(400).send(`Error: ${req.query.error}`);
  }

  const response = await fetch('https://api.aries.com/v1/oauth2/token', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      client_id: process.env.ARIES_CLIENT_ID,
      client_secret: process.env.ARIES_CLIENT_SECRET,
      grant_type: 'code',
      code: req.query.code,
      redirect_uri: process.env.ARIES_REDIRECT_URI,
    }),
  });

  if (!response.ok) {
    return res.status(500).send('Token exchange failed');
  }

  const tokens = await response.json();
  req.session.access_token = tokens.access_token;
  req.session.refresh_token = tokens.refresh_token;

  res.redirect('/dashboard');
});

// Step 4: Use the token
app.get('/dashboard', async (req, res) => {
  if (!req.session.access_token) {
    return res.redirect('/login');
  }

  const accounts = await fetch('https://api.aries.com/v1/users/me/accounts', {
    headers: { 'Authorization': `Bearer ${req.session.access_token}` },
  }).then(r => r.json());

  res.json(accounts);
});

Next steps

OAuth2 Overview

Scopes, security, rate limits, and troubleshooting.

PKCE Flow

Implement OAuth2 for SPAs and mobile apps.

Token API Reference

Interactive token endpoint reference.

Quick Start

Get started in minutes.