Skip to main content

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: tenant_cloudvault
Validation:
  • Must be a valid, active tenant identifier
  • Must match the tenant context of the authenticated user
  • Case-sensitive

X-Forwarded-For

Type: string
Required: Yes (for compliance operations)
Format: IPv4 or IPv6 address
Client’s originating IP address. Critical for regulatory compliance (AML/KYC), fraud detection, and audit trails. Examples:
X-Forwarded-For: 192.168.1.100
X-Forwarded-For: 2001:0db8:85a3:0000:0000:8a2e:0370:7334
When Required:
  • Customer registration (individual and organization)
  • Session creation (login)
  • Consent acceptance
  • Account activation
  • Transaction execution
  • Document submission
Compliance Notes:
  • Captured and stored permanently for regulatory audits
  • Used for geolocation-based compliance checks
  • Required for GDPR, AML, and KYC regulations
  • Cannot be modified after capture
Implementation:
  • If using a proxy/load balancer, forward the original client IP
  • For direct connections, use the client’s actual IP address
  • For mobile apps, use device’s current IP address
  • For server-to-server calls, use the originating server’s IP
Missing or invalid X-Forwarded-For header will result in a 400 Bad Request error for compliance-critical operations.

User-Agent

Type: string
Required: Yes (for compliance operations)
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.

Optional Headers

Accept

Type: string
Required: No
Default: application/json
Format: MIME type
Specifies the desired response format. Example:
Accept: application/json

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',
    'X-Tenant-ID': process.env.FINHUB_TENANT_ID,
  },
});

// 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['X-Forwarded-For'] = getClientIP(); // Implement based on your setup
  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',
            'X-Tenant-ID': tenant_id,
        })
    
    def set_auth_token(self, token: str):
        self.session.headers['Authorization'] = f'Bearer {token}'
    
    def _add_compliance_headers(self, client_ip: str, user_agent: str = None):
        """Add compliance-required headers"""
        self.session.headers['X-Forwarded-For'] = client_ip
        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], client_ip: str) -> Dict[str, Any]:
        self._add_compliance_headers(client_ip)
        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='tenant_cloudvault')
client.set_auth_token('your_jwt_token')
result = client.register_customer(customer_data, client_ip='192.168.1.100')

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, String clientIp) 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")
            .addHeader("X-Tenant-ID", tenantId)
            .addHeader("Authorization", "Bearer " + authToken)
            .addHeader("X-Forwarded-For", clientIp)
            .addHeader("User-Agent", "finhub-sdk-java/1.5.0")
            .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, X-Forwarded-For, User-Agent
Response:
{
  "code": 400,
  "message": "Missing required header: X-Forwarded-For",
  "data": {
    "error": "MISSING_REQUIRED_HEADER",
    "requiredHeaders": ["X-Forwarded-For", "User-Agent", "X-Tenant-ID"]
  }
}

Invalid Authorization Token

Request:
POST /customer/individual/activation
Authorization: Bearer invalid_token_here
X-Tenant-ID: tenant_cloudvault
Response:
{
  "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: tenant_B
Response:
{
  "code": 403,
  "message": "Tenant mismatch: token tenant does not match X-Tenant-ID header",
  "data": {
    "error": "TENANT_MISMATCH"
  }
}

Security Best Practices

Token Management

  • Never expose JWT tokens in client-side code or logs
  • Store tokens securely (HTTP-only cookies, secure storage)
  • Implement token refresh mechanism before expiry
  • Revoke tokens on logout

IP Address Handling

  • Always forward the original client IP, not proxy/CDN IP
  • Validate IP address format before sending
  • Be aware of IPv4 vs IPv6 differences
  • Document IP handling in privacy policy

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:
FieldSourcePurposeRetention
IP AddressX-Forwarded-ForGeolocation, fraud detection, AML7 years
User AgentUser-AgentDevice fingerprinting, security7 years
TimestampSystemAudit trail, compliance reporting7 years
Request IDX-Request-ID or auto-generatedTracing, debugging90 days
Tenant IDX-Tenant-IDMulti-tenant isolationPermanent
User IDJWT claimsUser attributionPermanent

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


Changelog

VersionDateChanges
v2.12026-01-13Added compliance headers (X-Forwarded-For, User-Agent)
v2.02025-12-01Initial multi-tenant support with X-Tenant-ID