Agent700 API Authentication Guide
Overview
The Agent700 Platform API uses multiple authentication methods to provide secure access to its resources. This guide covers all authentication methods, token management, security features, and best practices.
Base URL: https://api.agent700.ai/api
Table of Contents
- Authentication Methods
- JWT Bearer Token Authentication
- App Password Authentication
- MCP Service Authentication
- Google OAuth Authentication
- Token Management
- Security Features
- Code Examples
- Best Practices
Authentication Methods
The Agent700 API supports three primary authentication methods:
- JWT Bearer Tokens - Primary method for web and mobile applications
- App Passwords - For programmatic access and API integrations
- MCP Service API Keys - For internal MCP service communication
Additionally, users can authenticate via:
- Google OAuth - Social login integration
JWT Bearer Token Authentication
JWT (JSON Web Token) Bearer authentication is the primary method for accessing the Agent700 API. All authenticated endpoints require a valid JWT access token in the Authorization header.
Obtaining Access Tokens
Access tokens are obtained through one of three login endpoints:
1. Email/Password Login
Endpoint: POST /api/auth/login
Request:
{
"email": "[email protected]",
"password": "SecurePass123!"
}Response:
{
"email": "[email protected]",
"accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"expiresIn": 28800,
"organizationsRoles": [
{
"name": "Public",
"id": "org-uuid",
"role": "consumer"
}
],
"defaultOrganization": {
"id": "org-uuid",
"name": "Public"
}
}Security Headers (automatically set):
Set-Cookie: refreshToken=...; HttpOnly; Secure; SameSite=Strict
2. Google OAuth Login
Endpoint: POST /api/auth/googleauth
Request:
{
"token": "google-id-token-from-oauth"
}Response: Same format as email/password login
3. App Password Login
Endpoint: POST /api/auth/app-login
Request:
{
"token": "app_a7_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}Response: Same format as email/password login, with additional fields:
{
"email": "[email protected]",
"accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"expiresIn": 43200,
"organizationsRoles": [...],
"defaultOrganization": {...},
"authType": "app_password",
"appPasswordName": "My API Integration"
}Using Access Tokens
Include the access token in the Authorization header of all authenticated requests:
Authorization: Bearer <your_access_token>
Example:
curl -X GET https://api.agent700.ai/api/agents \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."Token Structure
JWT tokens contain the following claims:
sub(subject): User IDexp(expiration): Token expiration timestampiat(issued at): Token issuance timestampauth_type: Authentication method used (password,google_oauth,app_password)app_password_id: App password ID (if using app password authentication)
Token Expiration
- Login tokens: 8 hours (configurable via
ACCESS_TOKEN_LOGIN_TIMEOUT_HOURS) - Refresh tokens: 4 hours (configurable via
ACCESS_TOKEN_REFRESH_TIMEOUT_HOURS) - App password tokens: 12 hours (configurable via
APP_PASSWORD_JWT_EXPIRY_HOURS)
When a token expires, you'll receive a 401 Unauthorized response. Use the refresh token mechanism to obtain a new access token.
App Password Authentication
App passwords provide a secure way to authenticate programmatic access without using your primary account password. They're ideal for:
- API integrations
- CI/CD pipelines
- Third-party applications
- Automated scripts
Creating App Passwords
Endpoint: POST /api/auth/app-passwords
Authentication: Requires JWT Bearer token
Request:
{
"name": "My API Integration",
"permissions": {}
}Response:
{
"id": "app-password-uuid",
"name": "My API Integration",
"token": "app_a7_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"createdAt": "2025-01-15T10:00:00Z",
"expiresAt": "2026-01-15T10:00:00Z",
"isActive": true,
"warning": "This token will only be shown once. Store it securely."
}Important: The full token is only displayed once during creation. Store it securely immediately.
App Password Format
App passwords follow this format:
- Prefix:
app_a7_ - Total length: 39 characters
- Format:
app_a7_+ 32 hexadecimal characters
Example: app_a7_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
Using App Passwords
App passwords can be used in two ways:
1. As Bearer Token (Direct Authentication)
Use the app password directly as a Bearer token:
curl -X GET https://api.agent700.ai/api/agents \
-H "Authorization: Bearer app_a7_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"2. Via App Login Endpoint
Exchange the app password for a JWT access token:
curl -X POST https://api.agent700.ai/api/auth/app-login \
-H "Content-Type: application/json" \
-d '{"token": "app_a7_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}'Managing App Passwords
List App Passwords: GET /api/auth/app-passwords
- Returns all active app passwords (without full tokens)
Delete App Password: DELETE /api/auth/app-passwords/<password_id>
- Revokes an app password immediately
App Password Security
- Expiration: App passwords have a default expiration (typically 1 year)
- Rate Limiting: App password authentication is rate-limited (30 requests per 60 seconds by default)
- Lockout: Failed authentication attempts can temporarily lock an app password
- Revocation: App passwords can be revoked at any time
MCP Service Authentication
The MCP (Model Context Protocol) service uses API key authentication for internal service-to-service communication.
API Key Format
MCP service authentication uses the X-API-Key header:
X-API-Key: <your-api-key>
When to Use
MCP service authentication is used when:
- The Flask application communicates with the MCP service
- Internal service-to-service requests are made
- MCP endpoints are accessed directly
Configuration
MCP API keys are configured via environment variables:
# MCP Service
export MCP_API_KEY="your-secure-api-key-here"
# Flask Application
export MCP_SERVICE_URL="http://localhost:8000"
export MCP_API_KEY="your-secure-api-key-here"Google OAuth Authentication
Agent700 supports Google OAuth for social login integration.
OAuth Flow
- Initiate OAuth: Redirect user to Google OAuth consent screen
- User Consent: User grants permissions
- Token Exchange: Exchange Google ID token for Agent700 access token
- Authentication: Use Agent700 access token for API requests
Token Exchange
Endpoint: POST /api/auth/googleauth
Request:
{
"token": "google-id-token-from-oauth-flow"
}Response: Same format as email/password login
Example:
curl -X POST https://api.agent700.ai/api/auth/googleauth \
-H "Content-Type: application/json" \
-d '{"token": "google-id-token-here"}'OAuth Configuration
Google OAuth requires the following configuration:
- Google Client ID
- Google Client Secret
- Redirect URI
- JavaScript origins
These are configured via environment variables (see shared/config.py).
Token Management
Access Token Lifecycle
- Obtain Token: Login via one of the authentication methods
- Use Token: Include in
Authorizationheader for API requests - Token Expiration: Token expires after configured timeout
- Refresh Token: Use refresh token to obtain new access token
- Token Rotation: New refresh token issued on each refresh
Refresh Token Mechanism
Refresh tokens are stored in httpOnly cookies and automatically managed by the client. The refresh endpoint handles token rotation automatically.
Endpoint: POST /api/auth/refresh
Request: No body required (refresh token from cookie)
Response:
{
"accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"expiresIn": 14400,
"message": "Token refreshed successfully"
}Security Headers (automatically set):
Set-Cookie: refreshToken=...; HttpOnly; Secure; SameSite=Strict
Device Fingerprinting
The Agent700 API uses device fingerprinting to enhance security:
Fingerprint Components:
- User-Agent header
- Accept-Language header
- Accept-Encoding header
- Screen resolution (via
X-Screen-Resolutionheader) - Timezone offset (via
X-Timezone-Offsetheader)
Fingerprint Matching:
- Exact match: 100% fingerprint match
- Fuzzy match: 85% similarity threshold for legitimate device changes
- Trusted devices: Up to 5 trusted device fingerprints per user
Client-Side Headers (optional but recommended):
X-Screen-Resolution: 1920x1080
X-Timezone-Offset: -300
Token Rotation
Token rotation is automatic and occurs on every refresh:
- Old refresh token is invalidated
- New refresh token is issued
- New access token is issued
- Device fingerprint is validated
This prevents token reuse and enhances security.
Security Features
Device Fingerprinting
Device fingerprinting binds tokens to specific device characteristics, preventing unauthorized access from different devices.
Benefits:
- Prevents token theft and cross-device usage
- Allows legitimate device changes (fuzzy matching)
- Maintains up to 5 trusted devices per user
Token Rotation
Every token refresh issues a new refresh token, invalidating the previous one:
- Prevents token replay attacks
- Limits exposure window if token is compromised
- Maintains session continuity for legitimate users
Rate Limiting
Authentication endpoints are rate-limited to prevent abuse:
- App password authentication: 30 requests per 60 seconds (configurable)
- Login attempts: Monitored and logged
- Token refresh: Rate-limited to prevent abuse
Security Event Logging
All authentication events are logged for security auditing:
user_login- Successful logintoken_refresh_success- Successful token refreshrefresh_token_validation_failed- Failed refresh attemptapp_password_auth_success- Successful app password authenticationapp_password_auth_failed- Failed app password authenticationuser_logout- Explicit logout
httpOnly Cookies
Refresh tokens are stored in httpOnly cookies:
- httpOnly: Prevents JavaScript access (XSS protection)
- Secure: Only sent over HTTPS
- SameSite=Strict: CSRF protection
Code Examples
JavaScript/TypeScript
Login and Store Token
async function login(email, password) {
const response = await fetch('https://api.agent700.ai/api/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ email, password }),
credentials: 'include' // Important for cookies
});
if (!response.ok) {
throw new Error('Login failed');
}
const data = await response.json();
// Store access token in memory (not localStorage for security)
sessionStorage.setItem('accessToken', data.accessToken);
return data;
}Making Authenticated Requests
async function getAgents() {
const token = sessionStorage.getItem('accessToken');
const response = await fetch('https://api.agent700.ai/api/agents', {
method: 'GET',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
credentials: 'include'
});
if (response.status === 401) {
// Token expired, refresh it
await refreshToken();
return getAgents(); // Retry request
}
return response.json();
}Token Refresh
async function refreshToken() {
const response = await fetch('https://api.agent700.ai/api/auth/refresh', {
method: 'POST',
credentials: 'include' // Sends httpOnly cookie
});
if (!response.ok) {
// Refresh failed, redirect to login
window.location.href = '/login';
return;
}
const data = await response.json();
sessionStorage.setItem('accessToken', data.accessToken);
return data;
}Using App Password
async function authenticateWithAppPassword(appPassword) {
const response = await fetch('https://api.agent700.ai/api/auth/app-login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ token: appPassword }),
});
const data = await response.json();
sessionStorage.setItem('accessToken', data.accessToken);
return data;
}
// Or use directly as Bearer token
async function useAppPasswordDirectly(appPassword) {
const response = await fetch('https://api.agent700.ai/api/agents', {
method: 'GET',
headers: {
'Authorization': `Bearer ${appPassword}`,
},
});
return response.json();
}Python
Login and Store Token
import requests
def login(email, password):
response = requests.post(
'https://api.agent700.ai/api/auth/login',
json={'email': email, 'password': password}
)
response.raise_for_status()
data = response.json()
return data['accessToken'], response.cookies
# Usage
access_token, cookies = login('[email protected]', 'password123')Making Authenticated Requests
def get_agents(access_token, cookies=None):
headers = {
'Authorization': f'Bearer {access_token}',
'Content-Type': 'application/json'
}
response = requests.get(
'https://api.agent700.ai/api/agents',
headers=headers,
cookies=cookies
)
if response.status_code == 401:
# Token expired, refresh it
new_token = refresh_token(cookies)
return get_agents(new_token, cookies)
response.raise_for_status()
return response.json()Token Refresh
def refresh_token(cookies):
response = requests.post(
'https://api.agent700.ai/api/auth/refresh',
cookies=cookies
)
response.raise_for_status()
data = response.json()
return data['accessToken']Using App Password
def authenticate_with_app_password(app_password):
# Method 1: Exchange for JWT token
response = requests.post(
'https://api.agent700.ai/api/auth/app-login',
json={'token': app_password}
)
response.raise_for_status()
return response.json()['accessToken']
# Method 2: Use directly as Bearer token
def use_app_password_directly(app_password):
headers = {
'Authorization': f'Bearer {app_password}',
'Content-Type': 'application/json'
}
response = requests.get(
'https://api.agent700.ai/api/agents',
headers=headers
)
response.raise_for_status()
return response.json()cURL Examples
Email/Password Login
curl -X POST https://api.agent700.ai/api/auth/login \
-H "Content-Type: application/json" \
-H "X-Screen-Resolution: 1920x1080" \
-H "X-Timezone-Offset: -300" \
-d '{
"email": "[email protected]",
"password": "SecurePass123!"
}' \
-c cookies.txtMaking Authenticated Request
curl -X GET https://api.agent700.ai/api/agents \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \
-b cookies.txtToken Refresh
curl -X POST https://api.agent700.ai/api/auth/refresh \
-H "Content-Type: application/json" \
-H "X-Screen-Resolution: 1920x1080" \
-H "X-Timezone-Offset: -300" \
-b cookies.txtApp Password Login
curl -X POST https://api.agent700.ai/api/auth/app-login \
-H "Content-Type: application/json" \
-d '{
"token": "app_a7_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}'Using App Password Directly
curl -X GET https://api.agent700.ai/api/agents \
-H "Authorization: Bearer app_a7_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"MCP Service Authentication
curl -X GET http://localhost:8000/mcp/servers \
-H "X-API-Key: your-api-key-here"Best Practices
Token Storage
DO:
- Store access tokens in memory (sessionStorage) for web applications
- Use httpOnly cookies for refresh tokens (handled automatically)
- Clear tokens on logout
- Implement token refresh logic
DON'T:
- Store tokens in localStorage (vulnerable to XSS)
- Store tokens in plain text files
- Commit tokens to version control
- Share tokens between users
Security Recommendations
- Always use HTTPS in production
- Implement token refresh before expiration
- Handle 401 responses by refreshing tokens
- Monitor security events for suspicious activity
- Rotate app passwords regularly
- Use device fingerprinting headers when available
- Implement proper error handling for authentication failures
Token Refresh Strategies
Proactive Refresh:
- Refresh token 5 minutes before expiration
- Prevents failed requests due to expired tokens
Reactive Refresh:
- Refresh token when receiving 401 Unauthorized
- Retry original request after refresh
Example Implementation:
// Proactive refresh
setInterval(async () => {
const tokenExpiry = getTokenExpiry();
const now = Date.now();
const fiveMinutes = 5 * 60 * 1000;
if (tokenExpiry - now < fiveMinutes) {
await refreshToken();
}
}, 60000); // Check every minuteApp Password Best Practices
- Use descriptive names for app passwords
- Limit app password scope with permissions
- Revoke unused app passwords regularly
- Store app passwords securely (password manager, secrets manager)
- Never share app passwords between services
- Monitor app password usage for suspicious activity
Error Handling
Always handle authentication errors gracefully:
try {
const response = await fetch(url, {
headers: {
'Authorization': `Bearer ${token}`
}
});
if (response.status === 401) {
// Token expired or invalid
await refreshToken();
// Retry request
} else if (response.status === 403) {
// Insufficient permissions
throw new Error('Access denied');
}
return response.json();
} catch (error) {
// Handle error appropriately
console.error('Request failed:', error);
}Support
For authentication issues or questions:
- Email: [email protected]
- API Status: Check
/api/auth/heartbeatendpoint
