Authentication
All requests to the AlphaSense Agent API must be authenticated using OAuth2. Initial authentication uses a password grant; subsequent token renewal uses a refresh token grant. This page covers how to obtain an access token, manage token lifecycle, and integrate authentication into your application.
Starting May 1, 2026, access token expiration will be 30 minutes (1800 seconds). Update
your token refresh logic to use the expires_in value returned by the authentication response.
Overview
The authentication flow is a single POST request to the AlphaSense authorization endpoint. You
supply your API key, client credentials, and user credentials; the server returns a time-limited
access token (along with a refresh token) that you attach to every subsequent API call as a Bearer
token.
Auth endpoint:
POST https://api.alpha-sense.com/auth
Request Parameters
The request requires a combination of header and body parameters. The body must be sent as
application/x-www-form-urlencoded.
| Parameter | Type | Location | Required | Description |
|---|---|---|---|---|
x-api-key | string | Header | Yes | Your AlphaSense API key. Identifies your registered application. |
grant_type | string | Body | Yes | "password" for initial authentication, or "refresh_token" to renew using a refresh token. |
username | string | Body | Yes | The email address associated with your AlphaSense account. |
password | string | Body | Yes | The password for your AlphaSense account. |
client_id | string | Body | Yes | The OAuth2 client ID issued to your application. |
client_secret | string | Body | Yes | The OAuth2 client secret issued to your application. |
The table above documents the password grant flow. When using grant_type=refresh_token, the
parameters differ — see below.
Refresh Token Request Parameters
When your access token expires, use the refresh token (received from a prior authentication
response) to obtain a new access token without re-submitting user credentials. Send a POST request
to the same auth endpoint.
| Parameter | Type | Location | Required | Description |
|---|---|---|---|---|
x-api-key | string | Header | Yes | Your AlphaSense API key. Identifies your registered application. |
grant_type | string | Body | Yes | Must be "refresh_token". |
client_id | string | Body | Yes | The OAuth2 client ID issued to your application. |
client_secret | string | Body | Yes | The OAuth2 client secret issued to your application. |
refresh_token | string | Body | Yes | The refresh token from a previous authentication or refresh token response. |
The username and password fields are not required (and should be omitted) when using
grant_type=refresh_token.
Never hard-code credentials in source files, commit them to version control, or expose them in client-side code. Always load credentials from environment variables or a secrets manager.
Token Response
A successful authentication request returns a JSON object containing your access token (a signed JWT) and refresh token.
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6Ikp...",
"refresh_token": "abcdef-9876-54...",
"token_type": "Bearer",
"expires_in": 86400
}
| Field | Type | Description |
|---|---|---|
access_token | string | Signed JWT used as the Bearer token in the Authorization header. |
refresh_token | string | Token used to obtain a new access token when the current one expires. |
token_type | string | Always "Bearer". |
expires_in | integer | Token lifetime in seconds. The default is 86400 (24 hours). |
The access_token is a signed JSON Web Token. Treat it as opaque — do not modify or re-sign
it; AlphaSense validates the signature on every request. The payload carries a userId claim that
is used by Token Revocation to identify the user when cascading refresh-token
revocation.
Using the Token
Attach the token to every API request in the Authorization header:
Authorization: Bearer <access_token>
Token Expiration and Refresh
Access tokens are valid for 24 hours from the time of issuance (moving to 30 minutes on May
1, 2026). The authentication response includes a refresh_token that you should securely store and
use to obtain a new access token when needed.
Recommended patterns:
- Cache the token along with its expiration timestamp. Before each API call, check whether the token is still valid.
- Handle 401 responses gracefully. If an API call returns
401 Unauthorized, re-authenticate and retry the request. - Avoid authenticating on every request. The token is valid for 24 hours, so there is no need to request a new one for each call.
Using the Refresh Token
To refresh an expired access token, send a POST request with grant_type=refresh_token instead of
password. This avoids re-sending user credentials.
- Python
- JavaScript
- cURL
import os
import requests
def refresh_access_token(refresh_token: str) -> dict:
"""Use a refresh token to obtain a new access token."""
url = "https://api.alpha-sense.com/auth"
headers = {
"x-api-key": os.environ["ALPHASENSE_API_KEY"],
"Content-Type": "application/x-www-form-urlencoded",
}
payload = {
"grant_type": "refresh_token",
"client_id": os.environ["ALPHASENSE_CLIENT_ID"],
"client_secret": os.environ["ALPHASENSE_CLIENT_SECRET"],
"refresh_token": refresh_token,
}
response = requests.post(url, headers=headers, data=payload)
response.raise_for_status()
return response.json()
async function refreshAccessToken(refreshToken) {
const url = 'https://api.alpha-sense.com/auth'
const params = new URLSearchParams({
grant_type: 'refresh_token',
client_id: process.env.ALPHASENSE_CLIENT_ID,
client_secret: process.env.ALPHASENSE_CLIENT_SECRET,
refresh_token: refreshToken,
})
const response = await fetch(url, {
method: 'POST',
headers: {
'x-api-key': process.env.ALPHASENSE_API_KEY,
'Content-Type': 'application/x-www-form-urlencoded',
},
body: params.toString(),
})
if (!response.ok) {
const errorBody = await response.text()
throw new Error(`Token refresh failed (${response.status}): ${errorBody}`)
}
return response.json()
}
curl -X POST "https://api.alpha-sense.com/auth" \
-H "x-api-key: ${ALPHASENSE_API_KEY}" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "client_id=${ALPHASENSE_CLIENT_ID}" \
-d "client_secret=${ALPHASENSE_CLIENT_SECRET}" \
-d "refresh_token=${REFRESH_TOKEN}"
Token Revocation
If you need to invalidate the access_token returned by POST /auth (see
Token Response) before it expires — for example,
on user logout — call the token revocation endpoint. Revocation is idempotent, so it is safe to
retry.
Revocation endpoint:
POST https://api.alpha-sense.com/auth/token/revoke
The access token to revoke is read from the Authorization: Bearer <access_token> header — not
from a token body field.
The request body is optional. To revoke only the access token, send no body and no
Content-Type header. To also revoke all of the user's Auth0 refresh tokens, send a JSON body with
Content-Type: application/json (see Request Body below).
Headers
| Header | Type | Required | Description |
|---|---|---|---|
x-api-key | string | Yes | Your AlphaSense API key. Identifies your registered application. |
Authorization | string | Yes | Bearer <access_token> — the access token to revoke. |
clientid | string | Yes | The OAuth2 client ID issued to your application. |
Content-Type | string | Required when sending body | Must be application/json when a request body is included. |
Request Body
When the body is omitted, only the access token in the Authorization header is revoked. To
additionally revoke all of the user's Auth0 refresh tokens, send the following JSON body with
Content-Type: application/json:
{
"revokeRefreshTokens": true
}
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
revokeRefreshTokens | boolean | No | false | When true, revokes all of the user's Auth0 refresh tokens in addition to the access token. |
Cascade revocation uses the userId claim on the access token's JWT to identify the user. If the
JWT lacks a userId claim, the request fails with 401 Unauthorized (see
Response Codes below).
If you send a request body without Content-Type: application/json, the call returns 200 OK but
the token is not actually revoked. Always include Content-Type: application/json whenever a
body is present.
Response Codes
| HTTP Status | Cause | Resolution |
|---|---|---|
200 | Revocation succeeded, or the token was already revoked. | None — the call is complete. The response body is empty. |
400 | Required header missing (Authorization or clientid). | Include all required headers and retry. |
401 | The Bearer token is invalid or expired, or revokeRefreshTokens=true was sent on a token whose JWT lacks a userId claim. | Re-authenticate via POST /auth only if the same revocation is still needed. An expired token is already non-usable. |
502 | The upstream auth service returned 5xx. | Revocation is idempotent — retry with exponential backoff. |
Examples
The examples below assume you already have a valid access_token (see
Code Examples below for how to obtain one). Set:
export ALPHASENSE_API_KEY="your-api-key"
export ALPHASENSE_CLIENT_ID="your-client-id"
export ALPHASENSE_ACCESS_TOKEN="the-access-token-to-revoke"
- Python
- JavaScript
- cURL
import os
import requests
URL = "https://api.alpha-sense.com/auth/token/revoke"
def revoke_access_token() -> None:
"""Revoke only the access token (no body)."""
response = requests.post(
URL,
headers={
"x-api-key": os.environ["ALPHASENSE_API_KEY"],
"Authorization": f"Bearer {os.environ['ALPHASENSE_ACCESS_TOKEN']}",
"clientid": os.environ["ALPHASENSE_CLIENT_ID"],
},
)
response.raise_for_status()
def revoke_access_and_refresh_tokens() -> None:
"""Revoke the access token AND all of the user's refresh tokens."""
response = requests.post(
URL,
headers={
"x-api-key": os.environ["ALPHASENSE_API_KEY"],
"Authorization": f"Bearer {os.environ['ALPHASENSE_ACCESS_TOKEN']}",
"clientid": os.environ["ALPHASENSE_CLIENT_ID"],
"Content-Type": "application/json",
},
json={"revokeRefreshTokens": True},
)
response.raise_for_status()
const URL = 'https://api.alpha-sense.com/auth/token/revoke'
async function revokeAccessToken() {
// Revoke only the access token (no body).
const response = await fetch(URL, {
method: 'POST',
headers: {
'x-api-key': process.env.ALPHASENSE_API_KEY,
Authorization: `Bearer ${process.env.ALPHASENSE_ACCESS_TOKEN}`,
clientid: process.env.ALPHASENSE_CLIENT_ID,
},
})
if (!response.ok) {
throw new Error(`Token revocation failed (${response.status})`)
}
}
async function revokeAccessAndRefreshTokens() {
// Revoke the access token AND all of the user's refresh tokens.
const response = await fetch(URL, {
method: 'POST',
headers: {
'x-api-key': process.env.ALPHASENSE_API_KEY,
Authorization: `Bearer ${process.env.ALPHASENSE_ACCESS_TOKEN}`,
clientid: process.env.ALPHASENSE_CLIENT_ID,
'Content-Type': 'application/json',
},
body: JSON.stringify({revokeRefreshTokens: true}),
})
if (!response.ok) {
throw new Error(`Token revocation failed (${response.status})`)
}
}
# Revoke only the access token (no body).
curl -X POST "https://api.alpha-sense.com/auth/token/revoke" \
-H "x-api-key: ${ALPHASENSE_API_KEY}" \
-H "Authorization: Bearer ${ALPHASENSE_ACCESS_TOKEN}" \
-H "clientid: ${ALPHASENSE_CLIENT_ID}"
# Revoke the access token AND all of the user's refresh tokens.
curl -X POST "https://api.alpha-sense.com/auth/token/revoke" \
-H "x-api-key: ${ALPHASENSE_API_KEY}" \
-H "Authorization: Bearer ${ALPHASENSE_ACCESS_TOKEN}" \
-H "clientid: ${ALPHASENSE_CLIENT_ID}" \
-H "Content-Type: application/json" \
-d '{"revokeRefreshTokens": true}'
Code Examples
The following examples read all credentials from environment variables. Set these before running:
export ALPHASENSE_API_KEY="your-api-key"
export ALPHASENSE_CLIENT_ID="your-client-id"
export ALPHASENSE_CLIENT_SECRET="your-client-secret"
export ALPHASENSE_EMAIL="your-email@example.com"
export ALPHASENSE_PASSWORD="your-password"
Full Authentication
- Python
- JavaScript
- cURL
import os
import requests
def get_access_token() -> str:
"""Authenticate with the AlphaSense API and return an access token."""
url = "https://api.alpha-sense.com/auth"
headers = {
"x-api-key": os.environ["ALPHASENSE_API_KEY"],
"Content-Type": "application/x-www-form-urlencoded",
}
payload = {
"grant_type": "password",
"username": os.environ["ALPHASENSE_EMAIL"],
"password": os.environ["ALPHASENSE_PASSWORD"],
"client_id": os.environ["ALPHASENSE_CLIENT_ID"],
"client_secret": os.environ["ALPHASENSE_CLIENT_SECRET"],
}
response = requests.post(url, headers=headers, data=payload)
response.raise_for_status()
token_data = response.json()
return token_data["access_token"]
if __name__ == "__main__":
token = get_access_token()
print("Token acquired (expires per expires_in)")
# Use the token in subsequent requests:
# headers = {"Authorization": f"Bearer {token}"}
async function getAccessToken() {
const url = 'https://api.alpha-sense.com/auth'
const params = new URLSearchParams({
grant_type: 'password',
username: process.env.ALPHASENSE_EMAIL,
password: process.env.ALPHASENSE_PASSWORD,
client_id: process.env.ALPHASENSE_CLIENT_ID,
client_secret: process.env.ALPHASENSE_CLIENT_SECRET,
})
const response = await fetch(url, {
method: 'POST',
headers: {
'x-api-key': process.env.ALPHASENSE_API_KEY,
'Content-Type': 'application/x-www-form-urlencoded',
},
body: params.toString(),
})
if (!response.ok) {
const errorBody = await response.text()
throw new Error(`Authentication failed (${response.status}): ${errorBody}`)
}
const tokenData = await response.json()
return tokenData.access_token
}
// Usage
getAccessToken()
.then(token => {
console.log('Token acquired (expires per expires_in)')
// Use the token in subsequent requests:
// const headers = { Authorization: `Bearer ${token}` };
})
.catch(err => console.error(err))
curl -X POST "https://api.alpha-sense.com/auth" \
-H "x-api-key: ${ALPHASENSE_API_KEY}" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password" \
-d "username=${ALPHASENSE_EMAIL}" \
-d "password=${ALPHASENSE_PASSWORD}" \
-d "client_id=${ALPHASENSE_CLIENT_ID}" \
-d "client_secret=${ALPHASENSE_CLIENT_SECRET}"
Token Caching Pattern
For applications that make many API calls, cache both tokens. When the access token expires, attempt a refresh token grant first. Fall back to a full password grant only if the refresh also fails (for example, if the refresh token itself has expired).
- Python
- JavaScript
- cURL
import os
import time
import requests
class AlphaSenseAuth:
"""Manages AlphaSense API authentication with automatic token refresh."""
AUTH_URL = "https://api.alpha-sense.com/auth"
def __init__(self):
self._token = None
self._refresh_token = None
self._expires_at = 0
def get_token(self) -> str:
"""Return a valid access token, refreshing if necessary."""
if self._token and time.time() < self._expires_at:
return self._token
# Try refresh token first (avoids re-sending user credentials)
if self._refresh_token:
try:
return self._authenticate_with_refresh_token()
except requests.HTTPError:
# Refresh token may have expired; fall back to password grant
pass
return self._authenticate_with_password()
def _authenticate_with_refresh_token(self) -> str:
"""Obtain a new access token using the refresh token."""
headers = {
"x-api-key": os.environ["ALPHASENSE_API_KEY"],
"Content-Type": "application/x-www-form-urlencoded",
}
payload = {
"grant_type": "refresh_token",
"client_id": os.environ["ALPHASENSE_CLIENT_ID"],
"client_secret": os.environ["ALPHASENSE_CLIENT_SECRET"],
"refresh_token": self._refresh_token,
}
response = requests.post(self.AUTH_URL, headers=headers, data=payload)
response.raise_for_status()
return self._store_tokens(response.json())
def _authenticate_with_password(self) -> str:
"""Obtain tokens using the password grant (initial auth or refresh fallback)."""
headers = {
"x-api-key": os.environ["ALPHASENSE_API_KEY"],
"Content-Type": "application/x-www-form-urlencoded",
}
payload = {
"grant_type": "password",
"username": os.environ["ALPHASENSE_EMAIL"],
"password": os.environ["ALPHASENSE_PASSWORD"],
"client_id": os.environ["ALPHASENSE_CLIENT_ID"],
"client_secret": os.environ["ALPHASENSE_CLIENT_SECRET"],
}
response = requests.post(self.AUTH_URL, headers=headers, data=payload)
response.raise_for_status()
return self._store_tokens(response.json())
def _store_tokens(self, data: dict) -> str:
"""Store tokens and expiration from an auth response."""
self._token = data["access_token"]
self._refresh_token = data.get("refresh_token", self._refresh_token)
# Refresh 5 minutes before actual expiry for safety
self._expires_at = time.time() + data["expires_in"] - 300
return self._token
def get_headers(self) -> dict:
"""Return headers dict ready for authenticated API calls."""
return {
"Authorization": f"Bearer {self.get_token()}",
"x-api-key": os.environ["ALPHASENSE_API_KEY"],
}
class AlphaSenseAuth {
static AUTH_URL = 'https://api.alpha-sense.com/auth'
constructor() {
this.token = null
this.refreshToken = null
this.expiresAt = 0
}
async getToken() {
if (this.token && Date.now() < this.expiresAt) {
return this.token
}
// Try refresh token first (avoids re-sending user credentials)
if (this.refreshToken) {
try {
return await this.#authenticateWithRefreshToken()
} catch {
// Refresh token may have expired; fall back to password grant
}
}
return this.#authenticateWithPassword()
}
async #authenticateWithRefreshToken() {
const params = new URLSearchParams({
grant_type: 'refresh_token',
client_id: process.env.ALPHASENSE_CLIENT_ID,
client_secret: process.env.ALPHASENSE_CLIENT_SECRET,
refresh_token: this.refreshToken,
})
const response = await fetch(AlphaSenseAuth.AUTH_URL, {
method: 'POST',
headers: {
'x-api-key': process.env.ALPHASENSE_API_KEY,
'Content-Type': 'application/x-www-form-urlencoded',
},
body: params.toString(),
})
if (!response.ok) {
const errorBody = await response.text()
throw new Error(`Token refresh failed (${response.status}): ${errorBody}`)
}
return this.#storeTokens(await response.json())
}
async #authenticateWithPassword() {
const params = new URLSearchParams({
grant_type: 'password',
username: process.env.ALPHASENSE_EMAIL,
password: process.env.ALPHASENSE_PASSWORD,
client_id: process.env.ALPHASENSE_CLIENT_ID,
client_secret: process.env.ALPHASENSE_CLIENT_SECRET,
})
const response = await fetch(AlphaSenseAuth.AUTH_URL, {
method: 'POST',
headers: {
'x-api-key': process.env.ALPHASENSE_API_KEY,
'Content-Type': 'application/x-www-form-urlencoded',
},
body: params.toString(),
})
if (!response.ok) {
const errorBody = await response.text()
throw new Error(`Authentication failed (${response.status}): ${errorBody}`)
}
return this.#storeTokens(await response.json())
}
#storeTokens(data) {
this.token = data.access_token
this.refreshToken = data.refresh_token ?? this.refreshToken
// Refresh 5 minutes before actual expiry for safety
this.expiresAt = Date.now() + (data.expires_in - 300) * 1000
return this.token
}
async getHeaders() {
return {
Authorization: `Bearer ${await this.getToken()}`,
'x-api-key': process.env.ALPHASENSE_API_KEY,
}
}
}
#!/usr/bin/env bash
# Store tokens in variables for reuse across multiple requests
# Initial authentication with password grant
TOKENS=$(curl -s -X POST "https://api.alpha-sense.com/auth" \
-H "x-api-key: ${ALPHASENSE_API_KEY}" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password" \
-d "username=${ALPHASENSE_EMAIL}" \
-d "password=${ALPHASENSE_PASSWORD}" \
-d "client_id=${ALPHASENSE_CLIENT_ID}" \
-d "client_secret=${ALPHASENSE_CLIENT_SECRET}")
TOKEN=$(echo "$TOKENS" | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
REFRESH_TOKEN=$(echo "$TOKENS" | python3 -c "import sys,json; print(json.load(sys.stdin).get('refresh_token',''))")
echo "Token acquired. Use it in subsequent requests:"
echo " curl -H \"Authorization: Bearer \$TOKEN\" ..."
# Later: refresh the token without re-sending credentials
REFRESHED=$(curl -s -X POST "https://api.alpha-sense.com/auth" \
-H "x-api-key: ${ALPHASENSE_API_KEY}" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "client_id=${ALPHASENSE_CLIENT_ID}" \
-d "client_secret=${ALPHASENSE_CLIENT_SECRET}" \
-d "refresh_token=${REFRESH_TOKEN}")
TOKEN=$(echo "$REFRESHED" | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
echo "Token refreshed successfully."
Quick Validation
Use the following one-liners to verify that your credentials are configured correctly.
- Python
- JavaScript
- cURL
python3 -c "
import os, requests
r = requests.post('https://api.alpha-sense.com/auth',
headers={'x-api-key': os.environ['ALPHASENSE_API_KEY'], 'Content-Type': 'application/x-www-form-urlencoded'},
data={'grant_type':'password','username':os.environ['ALPHASENSE_EMAIL'],'password':os.environ['ALPHASENSE_PASSWORD'],
'client_id':os.environ['ALPHASENSE_CLIENT_ID'],'client_secret':os.environ['ALPHASENSE_CLIENT_SECRET']})
print('Success' if r.ok else f'Error {r.status_code}: {r.text}')
"
node -e "
(async()=>{const r=await fetch('https://api.alpha-sense.com/auth',{method:'POST',
headers:{'x-api-key':process.env.ALPHASENSE_API_KEY,'Content-Type':'application/x-www-form-urlencoded'},
body:new URLSearchParams({grant_type:'password',username:process.env.ALPHASENSE_EMAIL,
password:process.env.ALPHASENSE_PASSWORD,client_id:process.env.ALPHASENSE_CLIENT_ID,
client_secret:process.env.ALPHASENSE_CLIENT_SECRET}).toString()});
console.log(r.ok?'Success':'Error '+r.status+': '+await r.text())})()
"
curl -s -o /dev/null -w "%{http_code}" -X POST "https://api.alpha-sense.com/auth" \
-H "x-api-key: ${ALPHASENSE_API_KEY}" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password&username=${ALPHASENSE_EMAIL}&password=${ALPHASENSE_PASSWORD}&client_id=${ALPHASENSE_CLIENT_ID}&client_secret=${ALPHASENSE_CLIENT_SECRET}" \
| xargs -I {} sh -c 'if [ "{}" = "200" ]; then echo "Success"; else echo "Error: HTTP {}"; fi'
Error Handling
Common authentication errors and how to resolve them:
| HTTP Status | Cause | Resolution |
|---|---|---|
400 | Missing or malformed request parameters | Verify all required fields are present and grant_type is "password" or "refresh_token". |
401 | Invalid credentials or expired token | Check your username, password, client ID, and client secret. |
403 | Valid credentials but insufficient permissions | Confirm your API key is active and your account has Agent API access. |
429 | Too many authentication requests | Implement token caching to reduce auth calls. Back off and retry. |
500 | Server-side error | Retry after a brief delay. Contact support if the issue persists. |
The AlphaSense Agent API uses the same authentication mechanism as all other AlphaSense APIs. If you have already integrated with another AlphaSense API, you can reuse the same credentials and token.
- API Quick Start -- Get started with the full AlphaSense API suite using the same auth flow.
- Explorer -- Interactively test API endpoints with your credentials.