Skip to main content
The Aries API uses OAuth2 Authorization Code flows for authentication. In plain English: your app sends the user to Aries to log in, the user approves what your app is allowed to see/do, and Aries hands your app an access token that you include in every API call to prove who you are and what you’re allowed to do. Tokens expire on a schedule, so Aries also gives you a refresh token that you can swap for a fresh access token without re-prompting the user. Pick the flow that matches the kind of app you’re building (see Choose your flow below).
New to OAuth2? Don’t worry about reading this whole page first — head to the Quick Start to get a working API call in a few minutes, then come back here when you need the details.

Endpoints

PurposeEndpoint
Authorizationhttps://app.aries.com/oauth2/authorize
Token exchange & refreshPOST https://api.aries.com/v1/oauth2/token

Before you start

If OAuth2 is new to you, this is the easiest way to think about it:
  1. Your app asks the user to sign in with Aries.
  2. Aries sends your app a short-lived authorization code.
  3. Your app sends that code to the token endpoint.
  4. Aries returns an access token and usually a refresh token.
  5. Your app uses the access token when calling Aries APIs.
There is only one token endpoint: POST /v1/oauth2/token. That endpoint can be used in two different ways:
  1. Code exchange: trade an authorization code for tokens.
  2. Refresh: trade a refresh token for a new access token.
For the code exchange, there are two security styles:
  1. Server-side / confidential client: send client_secret
  2. PKCE / public client: send code_verifier
So the flow is not “three different token endpoints.” It is one token endpoint with a few different valid request shapes depending on what your app is doing.

Key terms in plain English

TermWhat it means
client_idThe public identifier for your app
client_secretA private password for your app. Only safe on a backend server
authorization codeA short-lived one-time code Aries sends back after login
access_tokenThe token you send with API requests
refresh_tokenA token you use later to get a new access token
redirect_uriThe URL Aries sends the user back to after login
scopeA list of permissions your app is asking for
stateA random value used to protect the login flow from tampering
code_verifierA one-time secret used by PKCE instead of client_secret
code_challengeA hashed version of the code_verifier sent earlier in the flow
If your app has a backend server that can safely store secrets, use the Authorization Code flow with client_secret. If your app runs in the browser or on a phone, use PKCE with code_verifier.

Available Scopes

What’s a scope? A scope is a label that says “this app is allowed to do X.” When you redirect the user to log in, you pass a list of scopes you need. The consent screen shows the user exactly what you’re asking for, and the access token they approve will only work for those things. Rule of thumb: request the smallest set of scopes that lets your app do its job. Asking for more than you need scares users away on the consent screen and increases the blast radius if a token leaks.
ScopeDescriptionExample endpoints
user:informationView user profile and personal detailsPATCH /v1/users/me
GET /v1/users/me/profile
account:informationView account balances, positions, and transaction historyGET /v1/users/me/accounts
GET /v1/accounts/{id}/balances
GET /v1/accounts/{id}/positions
order:executionPlace, modify, and cancel ordersPOST /v1/orders
PUT /v1/orders
DELETE /v1/orders
order:informationView order history, status, and execution reportsGET /v2/accounts/{id}/orders
position:informationView current positions and holdingsGET /v1/accounts/{id}/positions
market:informationAccess live and historical market dataGET /v1/marketdata/search
WSS /v1/market/ws
calendar:informationAccess earnings, economic, and market schedule dataGET /v1/calendars/economics
GET /v1/calendars/earnings
options:informationAccess options chains, Greeks, and expiration dataGET /v1/options/stocks/top-volume
GET /v1/options/etfs/top-volume
analytics:informationView analytics, ratings, and market insightsGET /v1/analytics/ratings
GET /v1/analytics/market-breadth
market:supplementalComprehensive market data: news, company profiles, financials, filings, ETF data, technical analysisGET /v1/news
GET /v1/company/profile
GET /v1/financials/statements
Specify multiple scopes as a space-separated string: account:information order:execution market:information

Choose your flow

There are two flows. Pick based on whether your app can keep a secret safe.

Authorization Code Flow

Use if: your app has a backend server (Node, Python, Go, Ruby, PHP, etc.) that can hold a client_secret that the user never sees. This is the standard, most-secure flow.

PKCE Flow

Use if: your app runs entirely in the browser (single-page app) or on a mobile device, where any ‘secret’ you ship can be extracted. PKCE swaps the secret for a per-request proof your app generates on the fly.

How it works

Both flows follow this sequence. The only difference is in step 6 — how your app proves it’s really yours when trading the one-time code for tokens:
  • Authorization Code flow — your backend sends its client_secret along with the code.
  • PKCE flow — your client sends a code_verifier (a random value it generated before step 2 and has been holding onto) that mathematically matches the code_challenge it sent at the start.
The end result is the same: Aries returns access_token (use this in API calls) and refresh_token (use this to get a new access token later without re-prompting the user).

What you send to the token endpoint

This is the part that usually confuses people, so here it is in a simple table.

1. When you are exchanging a login code on a backend server

Send:
  • grant_type: code
  • client_id
  • client_secret
  • code
  • redirect_uri
Use this when your app has a backend that can safely keep the client_secret private.

2. When you are exchanging a login code from a browser or mobile app

Send:
  • grant_type: code
  • client_id
  • code
  • redirect_uri
  • code_verifier
Use this for PKCE. You do not send client_secret here.

3. When your access token has expired and you want a new one

Send:
  • grant_type: refresh_token
  • client_id
  • client_secret
  • refresh_token
Use this after you already have tokens and only need a fresh access token.
The Aries backend uses a single request model for /v1/oauth2/token. What changes is which fields are required for the situation you are in.

Step-by-step walkthrough

Step 1: Register your app

Create an OAuth client in Client Center. You will get:
  • a client_id
  • a client_secret if your app is a confidential/server-side client
You also need to register the exact redirect_uri values your app will use.

Step 2: Send the user to Aries to sign in

Your app redirects the user to: https://app.aries.com/oauth2/authorize At this stage, you tell Aries:
  • which app is asking (client_id)
  • where to send the user back (redirect_uri)
  • which permissions you want (scope)
  • which response you want (response_type=code)
  • a random safety value (state)
  • for PKCE only: code_challenge and code_challenge_method

Step 3: User signs in and approves

The user sees the Aries login and consent screen. If they approve, Aries sends them back to your redirect_uri with a one-time code.

Step 4: Your app exchanges the code for tokens

Your app sends that code to: POST https://api.aries.com/v1/oauth2/token This is where the flow splits:
  • backend apps send client_secret
  • browser/mobile apps send code_verifier
If the request is valid, Aries returns:
  • access_token
  • refresh_token
  • expires_in
  • token_type
  • granted scope

Step 5: Call Aries APIs

Now your app can call protected endpoints by sending:
Authorization: Bearer YOUR_ACCESS_TOKEN

Step 6: Refresh when needed

When the access token expires, your app sends the refresh_token to the same token endpoint to get a new access token. This means the user usually does not need to sign in again every time a token expires.

Security Best Practices

Store credentials securely

Never hardcode client_secret or tokens in source code. Use environment variables or a secrets manager.

Use HTTPS only

Always use HTTPS for redirect URIs and all API calls in production. Never transmit credentials over HTTP.

Validate the state parameter

Always generate and verify state to prevent CSRF attacks. Generate a new random value per authorization request.

Rotate tokens proactively

Refresh access tokens before they expire. Persist any newly issued refresh_token returned in the response.

Rate Limits

Rate limits vary by endpoint category:

Authentication

10 requests/minute

User Management

100 requests/minute

Market Data

1,000 requests/minute

Trading

50 requests/minute
Rate limit headers are included in every response:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640000000
When you hit a rate limit (429 Too Many Requests), wait until X-RateLimit-Reset before retrying, or use exponential backoff.

Troubleshooting

Causes: The code expired (10 minutes) or was already exchanged (single-use).
Solution: Start the OAuth flow again and exchange the code immediately after receiving it.
Causes: Incorrect client_id or client_secret, or the client was deleted or disabled.
Solution: Verify credentials in Client Center. Regenerate client_secret if lost (it is shown only once).
Causes: Typo in scope name (case-sensitive) or scope not enabled for your client.
Solution: Check scope names against the Available Scopes table and client configuration.
Causes: The redirect_uri does not exactly match a registered URI (including protocol, path, and trailing slashes).
Solution: Register all redirect URIs in Client Center. Values must match character for character.
Cause: The user clicked “Deny” on the consent screen.
Solution: Show a clear message explaining why permissions are needed and offer a retry. Consider requesting fewer scopes if users frequently deny.

Next steps

Authorization Code Flow

Implement server-side OAuth2 with client_secret.

PKCE Flow

Implement OAuth2 for SPAs and mobile apps without client_secret.

OAuth2 Token API

Token endpoint reference and interactive testing.

Quick Start

Get your first API call working in minutes.