Generate secure tokens for frontend JavaScript authentication in 10 programming languages.
| Language | File |
|---|---|
| PHP | token-generator.php |
| Python | token-generator.py |
| JavaScript | token-generator.js |
| Java | TokenGenerator.java |
| Ruby | token_generator.rb |
| C# | TokenGenerator.cs |
| Go | token_generator.go |
| Rust | token_generator.rs |
| Swift | TokenGenerator.swift |
| Kotlin | TokenGenerator.kt |
git clone https://github.com/fcsapi/token-generator# PHP only
curl -O https://raw.githubusercontent.com/fcsapi/token-generator/main/token-generator.php
# Python only
curl -O https://raw.githubusercontent.com/fcsapi/token-generator/main/token-generator.py
# JavaScript only
curl -O https://raw.githubusercontent.com/fcsapi/token-generator/main/token-generator.js
# Java only
curl -O https://raw.githubusercontent.com/fcsapi/token-generator/main/TokenGenerator.java
# Ruby only
curl -O https://raw.githubusercontent.com/fcsapi/token-generator/main/token_generator.rb
# C# only
curl -O https://raw.githubusercontent.com/fcsapi/token-generator/main/TokenGenerator.cs
# Go only
curl -O https://raw.githubusercontent.com/fcsapi/token-generator/main/token_generator.go
# Rust only
curl -O https://raw.githubusercontent.com/fcsapi/token-generator/main/token_generator.rs
# Swift only
curl -O https://raw.githubusercontent.com/fcsapi/token-generator/main/TokenGenerator.swift
# Kotlin only
curl -O https://raw.githubusercontent.com/fcsapi/token-generator/main/TokenGenerator.ktGo to GitHub, click on the file you need, then click "Download raw file".
$generator = new FcsTokenGenerator('your_access_key', 'your_public_key');
$tokenData = $generator->generateToken();
// Returns: ['_token' => '...', '_expiry' => 1234567890, '_public_key' => '...']generator = FcsTokenGenerator('your_access_key', 'your_public_key')
token_data = generator.generate_token()
# Returns: {'_token': '...', '_expiry': 1234567890, '_public_key': '...'}const generator = new FcsTokenGenerator('your_access_key', 'your_public_key');
const tokenData = generator.generateToken();
// Returns: { _token: '...', _expiry: 1234567890, _public_key: '...' }TokenGenerator generator = new TokenGenerator("your_access_key", "your_public_key");
Map<String, Object> tokenData = generator.generateToken();generator = FcsTokenGenerator.new('your_access_key', 'your_public_key')
token_data = generator.generate_tokenvar generator = new TokenGenerator("your_access_key", "your_public_key");
var tokenData = generator.GenerateToken();generator := NewTokenGenerator("your_access_key", "your_public_key", 3600)
tokenData := generator.GenerateToken()let generator = TokenGenerator::new("your_access_key", "your_public_key", None);
let token_data = generator.generate_token();let generator = FcsTokenGenerator(accessKey: "your_access_key", publicKey: "your_public_key")
let tokenData = generator.generateToken()val generator = FcsTokenGenerator("your_access_key", "your_public_key")
val tokenData = generator.generateToken()| Seconds | Duration |
|---|---|
| 300 | 5 minutes |
| 900 | 15 minutes |
| 1800 | 30 minutes |
| 3600 | 1 hour (default) |
| 86400 | 24 hours |
A standard JWT (header.payload.signature, HMAC-SHA256). The client sends only the JWT as jwt_token
(query string, POST form, JSON body, or the header Authorization: Bearer <jwt>). No _public_key, _expiry or access key.
The Bearer header counts only when its value is one of our JWTs and no other credential (access_key, jwt_token, _public_key, _token, _expiry) is sent; any other Bearer token is ignored.
$generator = new FcsTokenGenerator('your_access_key', 'your_public_key', 300);
$jwt = $generator->generateJwt(); // plain: works from any site (or from your Allowed Domains)
$jwt = $generator->generateJwt('customer.com'); // bound: only works from a page on customer.comconst generator = new FcsTokenGenerator('your_access_key', 'your_public_key', 300);
const jwt = generator.generateJwt(); // or generator.generateJwt('customer.com')https://api-v4.fcsapi.com/forex/latest?symbol=EUR/USD&jwt_token=<jwt>
Make it in any language (or with any JWT library):
| Part | Value |
|---|---|
| header | {"alg":"HS256","typ":"JWT"}, base64url |
| payload | {"pub":"<public key>","exp":<unix seconds, a number>}, base64url (a whole number is best; a decimal is accepted and rounded down, text in quotes is not) |
| signature | HMAC-SHA256(header.payload, KEY) raw bytes, base64url, exactly 43 characters (no = padding, no spaces or line breaks) |
| KEY, plain token | your access key |
| KEY, token for one site | hex(HMAC-SHA256(message = "jwt |
domain is the exact page host the browser sends as Origin, lowercase, without https://, www. and port (customer.com).
The token does not say whether it is bound; the server tries the domain of the request first, then the plain key.
A bound token needs a browser (or any client that sends that Origin or Referer): a call from a server has neither and fails with invalid_token, so give servers a plain token.
The "jwt|" label in the key formula is required: a key made from the bare domain does not verify.
Never put the access key inside a token or in browser code. The API does not limit how far away exp is: the mint endpoint below caps a token at 86400 seconds, but a token you sign yourself can live longer, so keep it short.
You can also get a JWT from the API without writing code:
https://api-v4.fcsapi.com/forex/jwt_token?access_key=YOUR_ACCESS_KEY&expiry=300 (optional &domain=customer.com, one valid host, otherwise error 112; default expiry 3600, allowed 30 to 86400).
The answer holds jwt_token (send this), public_key, expiry, expires_in and, when you sent domain, domain.
A widget key or a RapidAPI call can never create a token (error 104).
If the key has "Allowed Domains (Public Key)" saved, a plain token must come from one of them, or from a server IP listed in "IP Authorizations" (a pass list for servers); with an empty list a plain token works anywhere. A token bound to a site skips that list.
Errors are code 101 with short_code invalid_format, invalid_publickey, expire_token, invalid_token or invalid_domain.
The old format (_public_key + _expiry + _token, generated by generateToken()) keeps working.
- Backend generates a secure token using HMAC-SHA256
- Backend sends token data to frontend (via API or meta tags)
- Frontend uses token for FCS API calls (no API key exposed)
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Backend │ │ Frontend │ │ FCS API │
│ (Your Server) │ │ (Browser) │ │ │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
│ 1. Generate Token │ │
│ (using access_key) │ │
│ │ │
│ 2. Send token data │ │
│ ─────────────────────────>│ │
│ │ │
│ │ 3. API Request │
│ │ (with token) │
│ │ ─────────────────────────>│
│ │ │
│ │ 4. Response │
│ │ <─────────────────────────│
│ │ │
- Email: support@fcsapi.com
- Website: fcsapi.com
MIT License - see LICENSE file for details.