Standard HTTP Headers
Required and optional HTTP headers for Finhub API requests
Standard HTTP Headers
All Finhub API requests require specific HTTP headers for authentication, tenant identification, compliance tracking, and proper request handling.
Required Headers
Authorization
Type: string
Required: Yes (except for public endpoints)
Format: Bearer <JWT_TOKEN>
Bearer token for API authentication. Obtained from the session creation endpoint after successful login.
Example:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
When Required:
- All authenticated API operations
- Customer operations (registration, verification, consents)
- Financial operations (transfers, beneficiaries, payment consents)
- Administrative operations
X-Tenant-ID
Type: string
Required: Yes (all endpoints)
Format: Alphanumeric tenant identifier
Identifies the tenant context for multi-tenant operations. Must match the tenant associated with the authenticated user or admin token.
Example:
X-Tenant-ID: 97e7ff29-15f3-49ef-9681-3bbfcce4f6cd
Validation:
- Must be a valid, active tenant identifier (UUID format)
- Must match the tenant context of the authenticated user
- Case-sensitive
User-Agent
Type: string
Required: Yes (all endpoints — enforced by global request filter)
Format: Standard User-Agent string
Client application identifier including browser, mobile app, or SDK version. Used for security analysis, device fingerprinting, and compliance reporting.
Examples:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
User-Agent: FinhubApp/2.1.0 (iOS 15.0; iPhone13,2)
User-Agent: finhub-sdk-js/1.5.0 Node/18.12.0
Format Guidelines:
- Browser: Use standard browser User-Agent
- Mobile Apps:
{AppName}/{Version} ({OS} {OSVersion}; {DeviceModel}) - SDKs:
finhub-sdk-{language}/{version} {runtime}/{runtime_version}
When Required:
- Customer registration
- Session creation
- Consent acceptance
- Transaction operations
- Document uploads
Security & Compliance:
- Used for device fingerprinting and fraud detection
- Helps identify suspicious access patterns
- Required for security audit trails
- Analyzed for bot detection and abuse prevention
Content-Type
Type: string
Required: Yes (for requests with body)
Format: MIME type
Specifies the media type of the request body.
Common Values:
Content-Type: application/json
Content-Type: multipart/form-data (for file uploads)
Content-Type: application/x-www-form-urlencoded
Default: application/json for all API endpoints unless otherwise specified.
X-Forwarded-From
Type: string
Required: Yes
Format: Source identifier string
Identifies the originating source of the request for tracking and routing purposes.
Example:
X-Forwarded-From: e2e-test
When Required:
- All API requests through the BFF layer
- Helps identify the upstream caller (frontend app, test suite, integration partner)
platform
Type: string
Required: Yes (all endpoints — enforced by global request filter)
Format: Platform identifier
Identifies the client platform making the request. Used for analytics, feature gating, and device-specific behavior.
Example:
platform: web
Common Values:
web— Browser-based applicationios— iOS mobile applicationandroid— Android mobile application
deviceId
Type: string
Required: Yes (all endpoints — enforced by global request filter)
Format: Unique device identifier
Unique identifier for the device making the request. Used for session tracking, fraud detection, and device management.
Example:
deviceId: 356938035643809
When Required:
- All authenticated API operations
- Session creation and management
- Transaction operations
sec-ch-ua-platform
Type: string
Required: No (accepted as an alias for platform)
Format: Client hint platform string
Browser client hint indicating the user’s operating system platform. Automatically sent by modern browsers. This header is an accepted alias for the platform header — if sec-ch-ua-platform is present, the platform header requirement is satisfied.
Example:
sec-ch-ua-platform: "Windows"
When Required:
- Customer registration
- Session creation
- Account activation
- Verification operations
- Consent acceptance
- Transfer operations
Contextual Headers
These headers are required only for specific endpoint groups.
X-User-ID
Type: string
Required: Conditional
Format: User identifier string
Identifies the acting user within a customer or organization context. Required for operations that need user-level attribution.
Example:
X-User-ID: usr_a1b2c3d4
When Required:
- Consent acceptance
- Beneficiary management (create, delete)
- Payment consent management
- Order execution and cancellation
- Wallet operations (prepare, execute)
- Webhook subscription creation
- Verification approval
X-Session-ID
Type: string
Required: Conditional
Format: Session identifier string
Identifies the current user session. Required for 2FA and session-bound operations.
Example:
X-Session-ID: sess_x1y2z3
When Required:
- 2FA code sending
- 2FA verification
- Session-bound CMS operations
X-Organization-ID
Type: string
Required: Conditional
Format: Organization identifier string
Identifies the organization context for B2B operations. Required when acting within an organization scope.
Example:
X-Organization-ID: org_e5f6g7h8
When Required:
- Employee management (list, add)
- Director management
- Wallet balance queries (B2B)
- Customer transaction history (B2B)
X-User-Roles
Type: string
Required: Conditional
Format: Comma-separated role list
Specifies the roles of the acting user. Required for operations that enforce role-based access.
Example:
X-User-Roles: ADMIN_USER,COMPLIANCE_OFFICER
When Required:
- Verification approval
- Employee management (add with role assignment)
X-Consumer-ID
Type: string
Required: Conditional
Format: Consumer identifier string
Identifies the consumer context for wallet and transaction queries.
Example:
X-Consumer-ID: cons_i9j0k1l2
When Required:
- Customer transaction history
- Order detail retrieval
X-Activity-ID
Type: string
Required: Conditional
Format: Activity tracking identifier
Tracks activity flow for password recovery and similar multi-step operations.
Example:
X-Activity-ID: act_m3n4o5p6
When Required:
- Password forgot flow
Optional Headers
Accept
Type: string
Required: No (optional — defaults to application/json)
Default: application/json, text/plain, */*
Format: MIME type
Specifies the desired response format.
Example:
Accept: application/json, text/plain, */*
X-Idempotency-Key
Type: string
Required: No (recommended for financial operations)
Format: UUID v4
Unique identifier for idempotent request handling. Prevents duplicate transaction processing.
Example:
X-Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
When Recommended:
- Payment transfers
- Beneficiary creation
- Payment consent creation
- Any operation that modifies financial state
Behavior:
- If a request with the same idempotency key is received within 24 hours, the original response is returned
- Prevents accidental duplicate transactions due to network issues or retries
- Key expires after 24 hours
X-Request-ID
Type: string
Required: No
Format: UUID v4
Unique request identifier for tracing and debugging. Automatically generated if not provided.
Example:
X-Request-ID: 7c9e6679-7425-40de-944b-e07fc1f90ae7
Use Cases:
- Request tracing across microservices
- Debugging and troubleshooting
- Support ticket correlation
SDK Implementation Examples
JavaScript/TypeScript
import axios from 'axios';
const finhubClient = axios.create({
baseURL: 'https://sandbox.finhub.cloud/api/v2.1',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json, text/plain, */*',
'X-Tenant-ID': process.env.FINHUB_TENANT_ID,
'X-Forwarded-From': 'your-app-name',
'platform': 'web',
'deviceId': getDeviceId(),
},
});
// Add interceptor for authentication
finhubClient.interceptors.request.use((config) => {
const token = localStorage.getItem('authToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
// Add compliance headers
config.headers['User-Agent'] = 'finhub-sdk-js/1.5.0';
return config;
});
// Example: Register customer
const registerCustomer = async (customerData) => {
const response = await finhubClient.post('/customer/individual/registration', customerData);
return response.data;
};Python
import requests
import os
from typing import Dict, Any
class FinhubClient:
def __init__(self, tenant_id: str, base_url: str = 'https://sandbox.finhub.cloud/api/v2.1'):
self.base_url = base_url
self.tenant_id = tenant_id
self.session = requests.Session()
self.session.headers.update({
'Content-Type': 'application/json',
'Accept': 'application/json, text/plain, */*',
'X-Tenant-ID': tenant_id,
'X-Forwarded-From': 'your-app-name',
'platform': 'web',
'deviceId': 'your-device-id',
})
def set_auth_token(self, token: str):
self.session.headers['Authorization'] = f'Bearer {token}'
def _add_compliance_headers(self, user_agent: str = None):
"""Add compliance-required headers"""
if user_agent:
self.session.headers['User-Agent'] = user_agent
else:
self.session.headers['User-Agent'] = 'finhub-sdk-python/1.5.0'
def register_customer(self, customer_data: Dict[str, Any]) -> Dict[str, Any]:
self._add_compliance_headers()
response = self.session.post(
f'{self.base_url}/customer/individual/registration',
json=customer_data
)
response.raise_for_status()
return response.json()
# Usage
client = FinhubClient(tenant_id='97e7ff29-15f3-49ef-9681-3bbfcce4f6cd')
client.set_auth_token('your_jwt_token')
result = client.register_customer(customer_data)Java
import okhttp3.*;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
public class FinhubClient {
private final OkHttpClient client;
private final String baseUrl;
private final String tenantId;
private String authToken;
public FinhubClient(String tenantId) {
this.baseUrl = "https://sandbox.finhub.cloud/api/v2.1";
this.tenantId = tenantId;
this.client = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
}
public void setAuthToken(String token) {
this.authToken = token;
}
public Response registerCustomer(String customerJson) throws IOException {
RequestBody body = RequestBody.create(
customerJson,
MediaType.parse("application/json")
);
Request request = new Request.Builder()
.url(baseUrl + "/customer/individual/registration")
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json, text/plain, */*")
.addHeader("X-Tenant-ID", tenantId)
.addHeader("Authorization", "Bearer " + authToken)
.addHeader("X-Forwarded-From", "your-app-name")
.addHeader("User-Agent", "finhub-sdk-java/1.5.0")
.addHeader("platform", "web")
.addHeader("deviceId", "your-device-id")
.post(body)
.build();
return client.newCall(request).execute();
}
}Error Scenarios
Missing Required Header
Request:
POST /customer/individual/registration
Content-Type: application/json
# Missing X-Tenant-ID, User-AgentResponse:
{
"success": false,
"code": 400,
"message": "Missing required header(s)",
"data": {
"platform_accepted": ["sec-ch-ua-platform", "platform"],
"deviceId_accepted": ["deviceId", "X-Device-Id", "device-id"],
"missingHeaders": ["User-Agent", "platform", "deviceId"]
}
}Invalid Authorization Token
Request:
POST /customer/individual/activation
Authorization: Bearer invalid_token_here
X-Tenant-ID: 97e7ff29-15f3-49ef-9681-3bbfcce4f6cdResponse:
{
"code": 401,
"message": "Invalid or expired authentication token",
"data": {
"error": "INVALID_TOKEN"
}
}Tenant Mismatch
Request:
POST /customer/individual/registration
Authorization: Bearer <token_for_tenant_A>
X-Tenant-ID: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeeeResponse:
{
"code": 403,
"message": "Tenant mismatch: token tenant does not match X-Tenant-ID header",
"data": {
"error": "TENANT_MISMATCH"
}
}Security Best Practices
Token Management
User-Agent Best Practices
- Use descriptive User-Agent strings with version information
- Update User-Agent when releasing new app versions
- Include SDK version for better support diagnostics
- Avoid spoofing or randomizing User-Agent (triggers fraud detection)
Compliance & Audit
Data Captured
For each API request with compliance headers, the system captures:
| Field | Source | Purpose | Retention |
|---|---|---|---|
| Client Source | X-Forwarded-From | Request origin tracking | 7 years |
| User Agent | User-Agent | Device fingerprinting, security | 7 years |
| Timestamp | System | Audit trail, compliance reporting | 7 years |
| Request ID | X-Request-ID or auto-generated | Tracing, debugging | 90 days |
| Tenant ID | X-Tenant-ID | Multi-tenant isolation | Permanent |
| User ID | JWT claims | User attribution | Permanent |
Regulatory Compliance
The captured headers support compliance with:
- GDPR (General Data Protection Regulation): Right to audit, data processing records
- PSD2 (Payment Services Directive 2): Strong customer authentication
- AML (Anti-Money Laundering): Customer due diligence, transaction monitoring
- KYC (Know Your Customer): Identity verification, risk assessment
- eIDAS (Electronic Identification): Authentication and trust services
Related Documentation
JWT token management and session handling
Common error codes and resolution strategies
API security guidelines and recommendations
Complete OpenAPI schema reference
Changelog
| Version | Date | Changes |
|---|---|---|
| v2.1.1 | 2026-03-10 | Added X-Forwarded-From, platform, deviceId, sec-ch-ua-platform, X-User-ID, X-Session-ID, X-Organization-ID, X-User-Roles, X-Consumer-ID, X-Activity-ID headers; updated examples to UUID tenant IDs |
| v2.1.2 | 2026-03-14 | Removed X-Forwarded-For (CORS unsafe for browser clients); use X-Forwarded-From for client identification |
| v2.1 | 2026-01-13 | Added compliance headers (User-Agent) |
| v2.0 | 2025-12-01 | Initial multi-tenant support with X-Tenant-ID |