Token Generation
This page walks through the full flow: client registration, JWT creation, and obtaining access tokens.
1. Client Registration
1.1 Generate an RSA Key Pair
Generate an RSA key pair suitable for RS256 (2048-bit recommended):
openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -in private_key.pem -pubout -out public_key.pem
- Keep
private_key.pemsecret and secure - Use
public_key.pemfor registration
1.2 Register Your Public Key
Send public_key.pem to your Uzabase Customer Success Manager or appointed technical contact.
After registration, you will receive:
| Credential | Description |
|---|---|
client_id | Your client identifier |
kid | Key identifier linked to your registered public key |
You will use client_id as both iss and sub when generating JWTs.
2. Client Invocations
These steps are performed each time your client needs to authenticate and call the API.
2.1 Generate a JWT
Create a JWT with the following header and payload, then sign it with your private key using RS256.
JWT Structure
| Field | Value |
|---|---|
alg | RS256 |
typ | JWT |
kid | Key ID issued by Uzabase |
Claim Details
| Claim | Description |
|---|---|
iss | Issuer — your client_id |
sub | Subject — your client_id |
aud | Audience — must be https://datafeed.ub-speeda.com/token |
iat | Issued-at time (Unix timestamp) |
exp | Expiration time (Unix timestamp); within 5 minutes recommended |
jti | Unique ID per request (UUID recommended) |
Sample Code
- Python
- Java
- Node.js
- Kotlin
- Go
import jwt
import time
import uuid
private_key = open("private_key.pem").read()
payload = {
"iss": "YOUR_CLIENT_ID",
"sub": "YOUR_CLIENT_ID",
"aud": "https://datafeed.ub-speeda.com/token",
"iat": int(time.time()),
"exp": int(time.time()) + 300,
"jti": str(uuid.uuid4()),
}
signed_jwt = jwt.encode(
payload,
private_key,
algorithm="RS256",
headers={"kid": "YOUR_KID"},
)
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.*;
// Load private key from PEM file
String pem = new String(Files.readAllBytes(Paths.get("private_key.pem")))
.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replaceAll("\\s", "");
RSAPrivateKey privateKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(pem)));
Algorithm algorithm = Algorithm.RSA256(null, privateKey);
String signedJwt = JWT.create()
.withKeyId("YOUR_KID")
.withIssuer("YOUR_CLIENT_ID")
.withSubject("YOUR_CLIENT_ID")
.withAudience("https://datafeed.ub-speeda.com/token")
.withIssuedAt(new Date())
.withExpiresAt(new Date(System.currentTimeMillis() + 300_000))
.withJWTId(UUID.randomUUID().toString())
.sign(algorithm);
const jwt = require('jsonwebtoken');
const fs = require('fs');
const { v4: uuidv4 } = require('uuid');
const privateKey = fs.readFileSync('private_key.pem');
const signedJwt = jwt.sign(
{
iss: 'YOUR_CLIENT_ID',
sub: 'YOUR_CLIENT_ID',
aud: 'https://datafeed.ub-speeda.com/token',
jti: uuidv4(),
},
privateKey,
{
algorithm: 'RS256',
expiresIn: 300,
keyid: 'YOUR_KID',
}
);
import com.auth0.jwt.JWT
import com.auth0.jwt.algorithms.Algorithm
import java.security.KeyFactory
import java.security.interfaces.RSAPrivateKey
import java.security.spec.PKCS8EncodedKeySpec
import java.util.*
val pemContent = java.io.File("private_key.pem").readText()
.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replace("\\s".toRegex(), "")
val keyBytes = Base64.getDecoder().decode(pemContent)
val privateKey = KeyFactory.getInstance("RSA")
.generatePrivate(PKCS8EncodedKeySpec(keyBytes)) as RSAPrivateKey
val algorithm = Algorithm.RSA256(null, privateKey)
val signedJwt = JWT.create()
.withKeyId("YOUR_KID")
.withIssuer("YOUR_CLIENT_ID")
.withSubject("YOUR_CLIENT_ID")
.withAudience("https://datafeed.ub-speeda.com/token")
.withIssuedAt(Date())
.withExpiresAt(Date(System.currentTimeMillis() + 300_000))
.withJWTId(UUID.randomUUID().toString())
.sign(algorithm)
import (
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"os"
"time"
"github.com/golang-jwt/jwt/v5"
"github.com/google/uuid"
)
keyData, _ := os.ReadFile("private_key.pem")
block, _ := pem.Decode(keyData)
privateKey, _ := x509.ParsePKCS8PrivateKey(block.Bytes)
now := time.Now()
claims := jwt.MapClaims{
"iss": "YOUR_CLIENT_ID",
"sub": "YOUR_CLIENT_ID",
"aud": "https://datafeed.ub-speeda.com/token",
"iat": now.Unix(),
"exp": now.Add(5 * time.Minute).Unix(),
"jti": uuid.New().String(),
}
token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
token.Header["kid"] = "YOUR_KID"
signedJwt, _ := token.SignedString(privateKey.(*rsa.PrivateKey))
2.2 Request an Access Token
Exchange the signed JWT for an access token.
Endpoint: POST https://datafeed.ub-speeda.com/token
Request Parameters
| Parameter | Value |
|---|---|
grant_type | client_credentials (fixed) |
client_id | Your client_id |
client_assertion_type | urn:ietf:params:oauth:client-assertion-type:jwt-bearer (fixed) |
client_assertion | Your signed JWT from step 2.1 |
Example Response
{
"access_token": "xxx.yyy.zzz",
"token_type": "bearer",
"expires_in": 300
}
Sample Code
- Python
- Java
- Node.js
- Kotlin
- Go
import requests
response = requests.post(
"https://datafeed.ub-speeda.com/token",
headers={"Content-Type": "application/x-www-form-urlencoded"},
data={
"grant_type": "client_credentials",
"client_id": "YOUR_CLIENT_ID",
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"client_assertion": signed_jwt,
},
)
access_token = response.json()["access_token"]
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.*;
import java.nio.charset.StandardCharsets;
String body = "grant_type=client_credentials"
+ "&client_id=" + URLEncoder.encode("YOUR_CLIENT_ID", StandardCharsets.UTF_8)
+ "&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
+ "&client_assertion=" + URLEncoder.encode(signedJwt, StandardCharsets.UTF_8);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://datafeed.ub-speeda.com/token"))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
// Parse access_token from response.body() using your preferred JSON library
const params = new URLSearchParams({
grant_type: 'client_credentials',
client_id: 'YOUR_CLIENT_ID',
client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
client_assertion: signedJwt,
});
const response = await fetch('https://datafeed.ub-speeda.com/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: params.toString(),
});
const { access_token } = await response.json();
import java.net.URI
import java.net.URLEncoder
import java.net.http.*
import java.nio.charset.StandardCharsets
val body = listOf(
"grant_type" to "client_credentials",
"client_id" to "YOUR_CLIENT_ID",
"client_assertion_type" to "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"client_assertion" to signedJwt,
).joinToString("&") { (k, v) ->
"$k=${URLEncoder.encode(v, StandardCharsets.UTF_8)}"
}
val request = HttpRequest.newBuilder()
.uri(URI.create("https://datafeed.ub-speeda.com/token"))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build()
val response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString())
// Parse access_token from response.body() using your preferred JSON library
import (
"io"
"net/http"
"net/url"
"strings"
)
data := url.Values{
"grant_type": {"client_credentials"},
"client_id": {"YOUR_CLIENT_ID"},
"client_assertion_type": {"urn:ietf:params:oauth:client-assertion-type:jwt-bearer"},
"client_assertion": {signedJwt},
}
resp, _ := http.Post(
"https://datafeed.ub-speeda.com/token",
"application/x-www-form-urlencoded",
strings.NewReader(data.Encode()),
)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
// Unmarshal body JSON to extract access_token
2.3 Use the Access Token
Include the access token in the Authorization header for all API requests.
Sample Code
- Python
- Java
- Node.js
- Kotlin
- Go
import requests
response = requests.get(
"https://datafeed.ub-speeda.com/private-company/v1/companies",
headers={"Authorization": f"Bearer {access_token}"},
params={"country": "KOR"},
)
print(response.json())
import java.net.URI;
import java.net.http.*;
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://datafeed.ub-speeda.com/private-company/v1/companies?country=KOR"))
.header("Authorization", "Bearer " + accessToken)
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
const response = await fetch(
'https://datafeed.ub-speeda.com/private-company/v1/companies?country=KOR',
{
headers: { Authorization: `Bearer ${access_token}` },
}
);
const data = await response.json();
console.log(data);
import java.net.URI
import java.net.http.*
val request = HttpRequest.newBuilder()
.uri(URI.create("https://datafeed.ub-speeda.com/private-company/v1/companies?country=KOR"))
.header("Authorization", "Bearer $accessToken")
.GET()
.build()
val response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString())
println(response.body())
import (
"io"
"net/http"
)
req, _ := http.NewRequest(
"GET",
"https://datafeed.ub-speeda.com/private-company/v1/companies?country=KOR",
nil,
)
req.Header.Set("Authorization", "Bearer "+accessToken)
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
2.4 Quick Setup Guide
The following complete examples combine steps 2.1, 2.2, and 2.3 — generating the JWT, exchanging it for an access token, and making an API call — in a single runnable snippet.
Prerequisites
- Python
- Java
- Node.js
- Kotlin
- Go
Requires Python 3.8+.
pip install pyjwt[crypto] requests
Requires Java 11+. Add the following dependencies to your pom.xml or build.gradle:
<!-- Maven -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.4.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.0</version>
</dependency>
Requires Node.js 18+.
npm install jsonwebtoken uuid
Requires Kotlin 1.8+ and Java 11+. Add to your build.gradle.kts:
implementation("com.auth0:java-jwt:4.4.0")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.17.0")
Requires Go 1.21+.
go get github.com/golang-jwt/jwt/v5
go get github.com/google/uuid
- Python
- Java
- Node.js
- Kotlin
- Go
import jwt
import time
import uuid
import requests
# ── Step 2.1: Generate a JWT ─────────────────────────────────────────────────
private_key = open("private_key.pem").read()
signed_jwt = jwt.encode(
{
"iss": "YOUR_CLIENT_ID",
"sub": "YOUR_CLIENT_ID",
"aud": "https://datafeed.ub-speeda.com/token",
"iat": int(time.time()),
"exp": int(time.time()) + 300,
"jti": str(uuid.uuid4()),
},
private_key,
algorithm="RS256",
headers={"kid": "YOUR_KID"},
)
# ── Step 2.2: Request an Access Token ────────────────────────────────────────
token_response = requests.post(
"https://datafeed.ub-speeda.com/token",
headers={"Content-Type": "application/x-www-form-urlencoded"},
data={
"grant_type": "client_credentials",
"client_id": "YOUR_CLIENT_ID",
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"client_assertion": signed_jwt,
},
)
access_token = token_response.json()["access_token"]
# ── Step 2.3: Call the API ────────────────────────────────────────────────────
response = requests.get(
"https://datafeed.ub-speeda.com/private-company/v1/companies",
headers={"Authorization": f"Bearer {access_token}"},
params={"country": "KOR"},
)
print(response.json())
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.*;
// ── Step 2.1: Generate a JWT ─────────────────────────────────────────────────
String pem = new String(Files.readAllBytes(Paths.get("private_key.pem")))
.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replaceAll("\\s", "");
RSAPrivateKey privateKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(pem)));
String signedJwt = JWT.create()
.withKeyId("YOUR_KID")
.withIssuer("YOUR_CLIENT_ID")
.withSubject("YOUR_CLIENT_ID")
.withAudience("https://datafeed.ub-speeda.com/token")
.withIssuedAt(new Date())
.withExpiresAt(new Date(System.currentTimeMillis() + 300_000))
.withJWTId(UUID.randomUUID().toString())
.sign(Algorithm.RSA256(null, privateKey));
// ── Step 2.2: Request an Access Token ────────────────────────────────────────
String tokenBody = "grant_type=client_credentials"
+ "&client_id=" + URLEncoder.encode("YOUR_CLIENT_ID", StandardCharsets.UTF_8)
+ "&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
+ "&client_assertion=" + URLEncoder.encode(signedJwt, StandardCharsets.UTF_8);
HttpClient httpClient = HttpClient.newHttpClient();
HttpResponse<String> tokenResponse = httpClient.send(
HttpRequest.newBuilder()
.uri(URI.create("https://datafeed.ub-speeda.com/token"))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.ofString(tokenBody))
.build(),
HttpResponse.BodyHandlers.ofString()
);
String accessToken = new ObjectMapper()
.readTree(tokenResponse.body())
.get("access_token")
.asText();
// ── Step 2.3: Call the API ────────────────────────────────────────────────────
HttpResponse<String> apiResponse = httpClient.send(
HttpRequest.newBuilder()
.uri(URI.create("https://datafeed.ub-speeda.com/private-company/v1/companies?country=KOR"))
.header("Authorization", "Bearer " + accessToken)
.GET()
.build(),
HttpResponse.BodyHandlers.ofString()
);
System.out.println(apiResponse.body());
const jwt = require('jsonwebtoken');
const fs = require('fs');
const { v4: uuidv4 } = require('uuid');
// ── Step 2.1: Generate a JWT ─────────────────────────────────────────────────
const privateKey = fs.readFileSync('private_key.pem');
const signedJwt = jwt.sign(
{
iss: 'YOUR_CLIENT_ID',
sub: 'YOUR_CLIENT_ID',
aud: 'https://datafeed.ub-speeda.com/token',
jti: uuidv4(),
},
privateKey,
{ algorithm: 'RS256', expiresIn: 300, keyid: 'YOUR_KID' }
);
// ── Step 2.2: Request an Access Token ────────────────────────────────────────
const tokenResponse = await fetch('https://datafeed.ub-speeda.com/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: 'YOUR_CLIENT_ID',
client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
client_assertion: signedJwt,
}).toString(),
});
const { access_token } = await tokenResponse.json();
// ── Step 2.3: Call the API ────────────────────────────────────────────────────
const apiResponse = await fetch(
'https://datafeed.ub-speeda.com/private-company/v1/companies?country=KOR',
{ headers: { Authorization: `Bearer ${access_token}` } }
);
console.log(await apiResponse.json());
import com.auth0.jwt.JWT
import com.auth0.jwt.algorithms.Algorithm
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import java.net.URI
import java.net.URLEncoder
import java.net.http.*
import java.nio.charset.StandardCharsets
import java.security.KeyFactory
import java.security.interfaces.RSAPrivateKey
import java.security.spec.PKCS8EncodedKeySpec
import java.util.*
// ── Step 2.1: Generate a JWT ─────────────────────────────────────────────────
val pemContent = java.io.File("private_key.pem").readText()
.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replace("\\s".toRegex(), "")
val privateKey = KeyFactory.getInstance("RSA")
.generatePrivate(PKCS8EncodedKeySpec(Base64.getDecoder().decode(pemContent))) as RSAPrivateKey
val signedJwt = JWT.create()
.withKeyId("YOUR_KID")
.withIssuer("YOUR_CLIENT_ID")
.withSubject("YOUR_CLIENT_ID")
.withAudience("https://datafeed.ub-speeda.com/token")
.withIssuedAt(Date())
.withExpiresAt(Date(System.currentTimeMillis() + 300_000))
.withJWTId(UUID.randomUUID().toString())
.sign(Algorithm.RSA256(null, privateKey))
// ── Step 2.2: Request an Access Token ────────────────────────────────────────
val httpClient = HttpClient.newHttpClient()
val tokenBody = listOf(
"grant_type" to "client_credentials",
"client_id" to "YOUR_CLIENT_ID",
"client_assertion_type" to "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"client_assertion" to signedJwt,
).joinToString("&") { (k, v) -> "$k=${URLEncoder.encode(v, StandardCharsets.UTF_8)}" }
val tokenResponse = httpClient.send(
HttpRequest.newBuilder()
.uri(URI.create("https://datafeed.ub-speeda.com/token"))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.ofString(tokenBody))
.build(),
HttpResponse.BodyHandlers.ofString()
)
val accessToken = jacksonObjectMapper()
.readTree(tokenResponse.body())
.get("access_token")
.asText()
// ── Step 2.3: Call the API ────────────────────────────────────────────────────
val apiResponse = httpClient.send(
HttpRequest.newBuilder()
.uri(URI.create("https://datafeed.ub-speeda.com/private-company/v1/companies?country=KOR"))
.header("Authorization", "Bearer $accessToken")
.GET()
.build(),
HttpResponse.BodyHandlers.ofString()
)
println(apiResponse.body())
package main
import (
"crypto/rsa"
"crypto/x509"
"encoding/json"
"encoding/pem"
"fmt"
"io"
"net/http"
"net/url"
"os"
"strings"
"time"
"github.com/golang-jwt/jwt/v5"
"github.com/google/uuid"
)
func main() {
// ── Step 2.1: Generate a JWT ─────────────────────────────────────────────
keyData, _ := os.ReadFile("private_key.pem")
block, _ := pem.Decode(keyData)
privateKey, _ := x509.ParsePKCS8PrivateKey(block.Bytes)
now := time.Now()
token := jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims{
"iss": "YOUR_CLIENT_ID",
"sub": "YOUR_CLIENT_ID",
"aud": "https://datafeed.ub-speeda.com/token",
"iat": now.Unix(),
"exp": now.Add(5 * time.Minute).Unix(),
"jti": uuid.New().String(),
})
token.Header["kid"] = "YOUR_KID"
signedJwt, _ := token.SignedString(privateKey.(*rsa.PrivateKey))
// ── Step 2.2: Request an Access Token ────────────────────────────────────
tokenResp, _ := http.Post(
"https://datafeed.ub-speeda.com/token",
"application/x-www-form-urlencoded",
strings.NewReader(url.Values{
"grant_type": {"client_credentials"},
"client_id": {"YOUR_CLIENT_ID"},
"client_assertion_type": {"urn:ietf:params:oauth:client-assertion-type:jwt-bearer"},
"client_assertion": {signedJwt},
}.Encode()),
)
defer tokenResp.Body.Close()
tokenBody, _ := io.ReadAll(tokenResp.Body)
var tokenData struct {
AccessToken string `json:"access_token"`
}
json.Unmarshal(tokenBody, &tokenData)
accessToken := tokenData.AccessToken
// ── Step 2.3: Call the API ────────────────────────────────────────────────
req, _ := http.NewRequest(
"GET",
"https://datafeed.ub-speeda.com/private-company/v1/companies?country=KOR",
nil,
)
req.Header.Set("Authorization", "Bearer "+accessToken)
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
Notes
- Access tokens are intentionally short-lived (typically 5 minutes). Re-issue as needed.
- Protect your private key — never share it or commit it to version control.
- Each JWT must have a unique
jticlaim.