Welcome Dear Developer…
{
"risk_alert": {
"risk_score_10": 7.5,
"event_type": "Geopolitical",
"anticipated_delay": "10-14 days",
"recommendation":
"Reroute via Cape of Hope"
},
"signal_id": "fin-abc-123",
"divergence_score": 85,
"directional_bias":
"Uptrend Probability"
}
Analytical intelligence
for modern developers.
Built for Developers.
Powered by Intelligence.
HavenGroup is an established Technology conglomerate headquartered in Yaoundé, Cameroon, with offices in the United Kingdom (London), founded by Agbor Boris Ojongetik. We harness advanced analytics to empower your applications with intelligent insights.
Pan-African Roots
A recognized presence across Africa, driving digital transformation from our Yaoundé headquarters.
Cutting-Edge APIs
Purpose-built analytical APIs delivering supply chain risk, AML/KYC verification, financial signals, and market divergence data.
Enterprise Security
HMAC-SHA256 request signing, two-key authentication, zero-retention image processing, and rigorous infrastructure security at every layer.
Office 9700, 321-323 High Road, Chadwell Heath, Essex RM6 6AX. UK, East London, United Kingdom
Welcome,
Your address () is not yet verified. Check your inbox. API key generation and billing are disabled until verification.
Plan & Billing
Loading…Select a Plan
Ensure you have an API Key generated before upgrading.
API Keys
Loading your API keys…
API Usage
Loading usage statistics…
Test Your API
// Response will appear here…
Test AML/KYC Verification
Upload an ID document and a selfie. Processing happens asynchronously — you receive a
request_id immediately, and the result is pushed to your webhook URL when ready.
You can also poll manually below.
// Submit above to receive a request_id…
Poll for Result
Paste or edit the request_id below and click Poll to check the current status.
Streamline Your Integration
Our SDKs handle HMAC-SHA256 signing, error parsing, and typed methods — so you focus on building, not plumbing.
Installation
Node.js
# pnpm (recommended)
pnpm install @hgbest/api-sdk
# npm
npm install @hgbest/api-sdk
# yarn
yarn add @hgbest/api-sdk
Python
pip install hgbest-client-python
C# (.NET)
dotnet add package HgBestClient.CSharp
Getting Started
Initialize with your API Key and Secret. Always load credentials from environment variables — never hardcode secrets in client-side code.
Node.js
import { HgBestClient } from '@hgbest/api-sdk';
const client = new HgBestClient({
apiKey: process.env.HB_API_KEY,
apiSecret: process.env.HB_API_SECRET
});
// Risk alert
const risk = await client.risk.globalSupplyChainAlert({
material_type: "Lithium-ion batteries",
region_of_origin: "Global",
logistics_route: "Asia to Europe via Suez Canal"
});
console.log("Risk Score:", risk.risk_alert.risk_score_10);
// AML/KYC verification
const { request_id } = await client.amlKyc.verify({
id_image_base64: "data:image/jpeg;base64,...",
selfie_base64: "data:image/jpeg;base64,...",
webhook_url: "https://yourserver.com/webhook",
metadata: { customer_id: "cus_123" }
});
// Poll for result (or wait for webhook)
const result = await client.amlKyc.getRequest(request_id);
console.log("Verification status:", result.status);
Python
from hgbest_client import HgBestClientPython
client = HgBestClientPython(
api_key="pk-YOUR_API_KEY_HERE",
api_secret="sk-YOUR_API_SECRET_HERE"
)
# AML/KYC
response = client.aml_kyc.verify({
"id_image_base64": "data:image/jpeg;base64,...",
"selfie_base64": "data:image/jpeg;base64,...",
"webhook_url": "https://theirclient.com/webhook"
})
result = client.aml_kyc.get_request(response["request_id"])
print(result)
C# (.NET)
var client = new HgBestClientCSharp("pk-...", "sk-...");
dynamic response = await client.AmlKyc.Verify(new {
id_image_base64 = "data:image/jpeg;base64,...",
selfie_base64 = "data:image/jpeg;base64,...",
"webhook_url": "https://theirclient.com/webhook"
});
dynamic result = await client.AmlKyc.GetRequest((string)response.request_id);
Console.WriteLine(result);
Manual Integration (Any Language)
The API uses standard HTTP — implement HMAC-SHA256 authentication manually in any language.
- Generate your API Key/Secret from the Dashboard.
- Get the current Unix timestamp in milliseconds.
- Compute SHA256 of the request body (compact JSON). Use
""for empty body. - Build the string to sign:
HTTP_METHOD\nPATH\nTIMESTAMP\nBODY_HASH - HMAC-SHA256 sign it using your API Secret. Hex-encode the result.
- Send these headers:
X-API-KEY: [Your API Key] X-API-TIMESTAMP: [Timestamp] X-API-SIGNATURE: [Signature] Content-Type: application/json
Comprehensive Documentation
Everything you need to integrate analytical intelligence into your applications.
Authentication — The Two-Key System
pk-xxxx…
Identifies your application. Sent in X-API-KEY header.
sk-yyyy…
Signs your requests cryptographically. Never expose client-side.
https://hgbest-backend.onrender.com
Error Codes
Success — response body contains requested data.
Accepted — request received and processing (AML/KYC async flow).
Bad Request — malformed or missing parameters.
Unauthorized — missing or invalid credentials.
Forbidden — invalid API Key or signature mismatch.
Too Many Requests — usage limit exceeded.
Internal Server Error — unexpected backend failure.
Performance & Timeouts
AI-powered endpoints may take longer due to complex model reasoning and internal retry logic. The AML/KYC endpoint processes asynchronously — it returns immediately with a request_id and pushes results to your webhook.
AML/KYC: Returns a
202 Accepted immediately. Final result delivered via webhook (usually within 10–30 seconds).
Endpoints
/risk/global-supply-chain-alert
Identifies obscure global risks impacting materials or logistics routes. Provides actionable disruption predictions.
Request
{
"material_type": "Lithium-ion batteries",
"region_of_origin": "Global",
"logistics_route": "Asia to Europe via Suez Canal"
}
Response
{
"request_id": "risk-alert-abc-123",
"risk_alert": {
"risk_score_10": 7.5,
"event_type": "Geopolitical / Logistical Disruption",
"anticipated_delay_days": "10-14 days",
"summary": "Persistent rerouting via Cape of Good Hope…",
"immediate_recommendation": "Develop multi-modal logistics strategy."
}
}
/finance/macro-sentiment-score
Synthesizes market chatter, regulatory filings, and historical correlations into a quantifiable Portfolio Impact Signal.
Request
{
"market_focus": "Tech sector",
"regulatory_filings_keywords": ["SEC filing ABC"],
"news_keywords": ["AI regulation", "semiconductor shortage"]
}
Response
{
"signal_id": "finance-signal-def-456",
"overall_risk_signal": "Caution - Moderate Volatility Expected",
"impact_prediction": {
"score_0_100": 65,
"volatility_index_change": "+1.8%",
"key_insight": "Regulatory uncertainty driving market volatility."
},
"sector_exposure": [{
"sector": "Technology",
"exposure_level": "HIGH",
"sentiment_delta": -0.92
}]
}
/market/algorithmic-divergence-signal
Detects divergence between disparate data streams and asset price, signalling high-probability unexpected price movements.
Request
{
"asset_ticker": "BTC",
"additional_context": "Recent SEC comments, institutional adoption rising."
}
Response
{
"asset_ticker": "BTC",
"divergence_score_percent": 85,
"directional_bias": "Uptrend Probability",
"top_causal_factor": "Growing institutional capital inflows.",
"predictive_factors": [{
"name": "Social Sentiment (Weighted)",
"value": "0.88",
"description": "Significant positive sentiment across crypto channels."
}],
"advice": "Monitor for volume confirmation above $70,000."
}
/aml-kyc/verify
Async
Performs KYC (document extraction + face match) and AML (sanctions screening) on an ID document and selfie. Returns immediately with a request_id; final result is POSTed to your webhook_url.
Request
{
"id_image_base64": "data:image/jpeg;base64,/9j/4AAQ...",
"selfie_base64": "data:image/jpeg;base64,/9j/4BBR...",
"webhook_url": "https://yourserver.com/your-webhook",
"metadata": { "customer_id": "cus_123" }
}
Immediate Response (202 Accepted)
{
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "PROCESSING",
"submitted_at": "2025-06-01T12:00:00.000Z"
}
Webhook Payload (final result)
{
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "APPROVED",
"reason_codes": [],
"kyc": {
"document_type": "passport",
"full_name": "Jane Doe",
"expiry_date": "2030-05-14",
"is_expired": false,
"doc_confidence": 0.93
},
"face_match": { "score": 0.91, "passed": true },
"liveness": {
"appears_live": true,
"liveness_confidence": 0.92,
"passed": true,
"notes": null
},
"aml": { "sanctions_checked": true, "sanctions_hit": false }
}
Verifying the Webhook is Genuine
Every webhook POST from HgBest includes two headers you must verify:
X-HgBest-Signature — HMAC-SHA256 hex string (proof it is from us)
X-HgBest-Timestamp — Unix milliseconds
Our public webhook secret — copy this into your server:
hgbest_whsec_122f09c08413e62e79d95ccb233502554bc07564207c14315f9eebb8b312c28c
Node.js — verify and receive webhook:
const crypto = require('crypto');
app.post('/your-webhook', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-hgbest-signature'];
const timestamp = req.headers['x-hgbest-timestamp'];
const rawBody = req.body.toString('utf8');
const HGBEST_WEBHOOK_SECRET = 'hgbest_whsec_122f09c08413e62e79d95ccb233502554bc07564207c14315f9eebb8b312c28c';
const expected = crypto
.createHmac('sha256', HGBEST_WEBHOOK_SECRET)
.update(`${timestamp}.${rawBody}`)
.digest('hex');
if (signature !== expected) {
return res.status(401).send('Invalid webhook signature');
}
const result = JSON.parse(rawBody);
console.log('Status:', result.status);
console.log('Reason codes:', result.reason_codes);
res.status(200).send('OK');
});
Python — verify and receive webhook:
import hmac, hashlib, json
HGBEST_WEBHOOK_SECRET = 'hgbest_whsec_122f09c08413e62e79d95ccb233502554bc07564207c14315f9eebb8b312c28c'
def verify_hgbest_webhook(raw_body: str, timestamp: str, signature: str) -> bool:
message = f"{timestamp}.{raw_body}".encode('utf-8')
expected = hmac.new(
HGBEST_WEBHOOK_SECRET.encode('utf-8'),
message,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
# Flask example:
# @app.route('/your-webhook', methods=['POST'])
# def receive_webhook():
# raw_body = request.get_data(as_text=True)
# timestamp = request.headers.get('X-HgBest-Timestamp')
# signature = request.headers.get('X-HgBest-Signature')
# if not verify_hgbest_webhook(raw_body, timestamp, signature):
# return 'Invalid signature', 401
# result = json.loads(raw_body)
# print('Status:', result['status'])
# return 'OK', 200
Reason Codes
LIVENESS_FAILEDSelfie detected as a printed photo, screen recording, or mask — not a live person.
DOC_UNREADABLEID image too blurry or damaged to extract data.
DOC_EXPIREDDocument is past its expiry date.
DOC_UNSUPPORTEDDocument type not recognised.
FACE_MISMATCHSelfie does not match ID photo (score < 0.75).
FACE_UNDETECTABLENo face found in one or both images.
SANCTIONS_HITName found on a global sanctions list.
SANCTIONS_ERRORSanctions API unavailable (non-blocking).
LOW_CONFIDENCEAI confidence below acceptable threshold.
/aml-kyc/requests/:requestId
Poll for the outcome of a previously submitted verification. Only the API key that submitted the request can retrieve it.
Response
{
"request_id": "550e8400-...",
"status": "APPROVED",
"reason_codes": [],
"kyc_summary": { "document_type": "passport", "is_expired": false },
"face_match_score": 0.91,
"sanctions_hit": false,
"liveness_passed": true,
"submitted_at": "2025-06-01T12:00:00.000Z",
"completed_at": "2025-06-01T12:00:08.000Z"
}
Legal & Policies
Support & Community
Facing difficulties or need integration help? Our team responds within 24 business hours.
Choose Your Plan
Unlock higher limits, priority support, and AML/KYC verifications.
- ✓ 250 general requests
- ✓ 50 AML/KYC verifications
- ✓ Standard AI Models
- ✓ Basic email support
- ✓ All core endpoints
- ✓ Higher general request limit
- ✓ Higher AML/KYC quota
- ✓ Enhanced AI Models
- ✓ Priority email (24hr)
- ✓ 30-day data retention
- ✓ Highest general request limit
- ✓ Highest AML/KYC quota
- ✓ Premium AI Models
- ✓ Dedicated chat + email (4hr)
- ✓ Beta features access
- ✓ 90-day data retention
- ✓ Custom integrations
All paid plans are recurring subscriptions. Exact pricing and limits are configured dynamically. Cancel anytime via the Billing Portal.