Skip to main content

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.

Upcoming Token Expiration Change

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.

ParameterTypeLocationRequiredDescription
x-api-keystringHeaderYesYour AlphaSense API key. Identifies your registered application.
grant_typestringBodyYes"password" for initial authentication, or "refresh_token" to renew using a refresh token.
usernamestringBodyYesThe email address associated with your AlphaSense account.
passwordstringBodyYesThe password for your AlphaSense account.
client_idstringBodyYesThe OAuth2 client ID issued to your application.
client_secretstringBodyYesThe 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.

ParameterTypeLocationRequiredDescription
x-api-keystringHeaderYesYour AlphaSense API key. Identifies your registered application.
grant_typestringBodyYesMust be "refresh_token".
client_idstringBodyYesThe OAuth2 client ID issued to your application.
client_secretstringBodyYesThe OAuth2 client secret issued to your application.
refresh_tokenstringBodyYesThe refresh token from a previous authentication or refresh token response.
info

The username and password fields are not required (and should be omitted) when using grant_type=refresh_token.

Credential Security

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
}
FieldTypeDescription
access_tokenstringSigned JWT used as the Bearer token in the Authorization header.
refresh_tokenstringToken used to obtain a new access token when the current one expires.
token_typestringAlways "Bearer".
expires_inintegerToken lifetime in seconds. The default is 86400 (24 hours).
JWT format

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.

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()

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
Empty body or JSON body

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

HeaderTypeRequiredDescription
x-api-keystringYesYour AlphaSense API key. Identifies your registered application.
AuthorizationstringYesBearer <access_token> — the access token to revoke.
clientidstringYesThe OAuth2 client ID issued to your application.
Content-TypestringRequired when sending bodyMust 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
}
FieldTypeRequiredDefaultDescription
revokeRefreshTokensbooleanNofalseWhen 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).

Content-Type matters when sending a body

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 StatusCauseResolution
200Revocation succeeded, or the token was already revoked.None — the call is complete. The response body is empty.
400Required header missing (Authorization or clientid).Include all required headers and retry.
401The 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.
502The 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"
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()

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

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}"}

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).

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"],
}

Quick Validation

Use the following one-liners to verify that your credentials are configured correctly.

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}')
"

Error Handling

Common authentication errors and how to resolve them:

HTTP StatusCauseResolution
400Missing or malformed request parametersVerify all required fields are present and grant_type is "password" or "refresh_token".
401Invalid credentials or expired tokenCheck your username, password, client ID, and client secret.
403Valid credentials but insufficient permissionsConfirm your API key is active and your account has Agent API access.
429Too many authentication requestsImplement token caching to reduce auth calls. Back off and retry.
500Server-side errorRetry after a brief delay. Contact support if the issue persists.
Related APIs

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.