Skip to content
UseBullion Risk API · v1

Upstream risk infrastructure for private trading bots

Your bot decides what to trade. UseBullion decides whether it should — using real-time macro bias, central-bank stance, COT positioning, and news blackouts. One HTTP call, HMAC-signed decisions, full audit trail. No such layer exists elsewhere.

Composite macro bias
News, COT, and rates fused into a single directional score per account.
News blackout guard
Refuse entries within N minutes of high-impact events. Fail-closed on calendar errors.
HMAC-signed decisions
Every response carries X-UseBullion-Signature so you can prove UseBullion authored it.

Quickstart

  1. Sign in and mint a key in the Developer portal.
  2. Store it as USEBULLION_KEY in your bot's secret manager.
  3. On every entry signal your bot generates, POST to /api/public/v1/risk/precheck.
  4. If decision !== "approved", drop the trade — UseBullion has blocked it for a reason.
curl -X POST https://usebullion.com/api/public/v1/risk/precheck \
  -H "Authorization: Bearer ub_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "symbol": "XAUUSD", "side": "buy", "volume": 0.10, "requestId": "trade-abc-123" }'

Endpoints

POST
/api/public/v1/risk/precheck

Pre-trade decision

Body: { symbol?, side, volume?, requestId? }. Returns approved or blocked with reason code, macro factors, and audit metadata.
GET
/api/public/v1/risk/killswitch

Am I allowed to trade right now?

Cheap read. Returns { allowed, reasons[] } combining trial gate + news blackout.
GET
/api/public/v1/risk/stream

Live SSE feed (killswitch + decisions)

Server-Sent Events. Emits hello, killswitch (every 5s), and decisionframes as new precheck rows land. Every frame is HMAC-signed inside the payload. Auth viaAuthorization header or ?token= query param (for EventSource).
GET
/api/public/v1/macro/bias

Current composite bias

Returns bias (long / short / flat), score, confidence, and per-source factor breakdown.
POST
/api/public/v1/positions

Declare an open position

Body: { externalId?, symbol, side, volume, entryPrice?, sl?, tp?, status? }. Upserted by(user, externalId). Used to enforce net-exposure limits across your bots.
GET
/api/public/v1/positions

List open positions

Returns the caller's currently-open declared positions.
GET
/api/public/v1/decisions?since=ISO&limit=N

Signed audit trail

Every allow/block decision UseBullion made for this account. Ideal for compliance and post-mortems.

Authentication

Send your key in the Authorization header:

Authorization: Bearer ub_live_XXXXXXXX…

Keys are hashed at rest (SHA-256). UseBullion only ever shows the plaintext at creation time. Revoke instantly from the developer portal. Default rate limit: 60 requests per minute per key.

Verifying signed responses

Every response includes X-UseBullion-Signature: sha256=… and X-UseBullion-Timestamp. Verify with the shared signing secret UseBullion issues on request (contact support to enable outbound verification).

import crypto from "node:crypto";

function verify(body: string, signatureHeader: string, timestampHeader: string, secret: string) {
  const expected = "sha256=" + crypto
    .createHmac("sha256", secret)
    .update(`${timestampHeader}.${body}`)
    .digest("hex");
  // constant-time compare
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signatureHeader));
}

Error codes

HTTPcodeMeaning
400invalid_inputMissing or malformed field (e.g. side must be buy or sell).
401unauthorized / invalid_key / revokedBearer token missing, unknown, or revoked.
402upgrade_requiredFree-plan 7-day private-bot trial expired. Upgrade to continue.
403insufficient_scopeKey lacks the scope for this endpoint.
423news_blackout / macro_biasRisk engine actively blocked the trade.
429rate_limitedRate limit exceeded — back off and retry.
500server_error / db_errorUseBullion side error. Fail-closed: do not trade.

Ready to give your bot an institutional-grade risk layer? Mint your first key →