Documentation

Authenticate once, call anything in the OrientAPI suite.

Authentication

Every API uses the x-api-key header. Generate keys in your dashboard.

curl -X POST https://api.orient.dev/football \
  -H "x-api-key: of_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "homeTeam": "Manchester City",
    "awayTeam": "Liverpool",
    "competition": "Premier League"
  }'

Products & key prefixes

ProductPrefixBase URLStatus
OrientMusic APIom_https://api.orientapihub.com/musicLive
OrientVideo APIov_https://api.orientapihub.com/videoLive
OrientMusicVideo APIomv_https://api.orientapihub.com/music-videoLive
OrientFootball APIof_https://api.orientapihub.com/footballLive
OrientEsports APIoe_https://api.orientapihub.com/esportsLive
OrientVirtualFootball APIovf_https://api.orientapihub.com/virtual-footballLive
OrientBank APIob_https://api.orientapihub.com/bankLive
OrientImage APIoi_https://api.orientapihub.com/imageLive
OrientLLM APIollm_https://api.orientapihub.com/llmLive
OrientVoice APIovc_https://api.orientapihub.com/voiceLive
OrientCode APIoc_https://api.orientapihub.com/codeLive
OrientTranscription APIotr_https://api.orientapihub.com/transcriptionLive
OrientTranslation APIotl_https://api.orientapihub.com/translationLive
OrientAfricanLanguages APIoal_https://api.orientapihub.com/african-languagesLive
OrientScratch APIos_https://api.orientapihub.com/scratchLive
OrientLuckyTap APIolt_https://api.orientapihub.com/lucky-tapLive
OrientWheel APIow_https://api.orientapihub.com/wheelLive
OrientCrash APIocr_https://api.orientapihub.com/crashLive
Heritage Music Video APIhmv_https://api.orientapihub.com/heritage-music-video-appLive
Orient Movie APIomv2_https://api.orientapihub.com/orient-movie-apiLive
Orient Recharge APIorc_https://api.orientapihub.com/orient-recharge-apiLive

OrientFootball endpoints

MethodPathDescription
POST/api/footballMatch prediction
POST/api/football/detailedDetailed prediction with stats
GET/api/football/competitionsList all competitions
GET/api/football/teamsList all teams
GET/api/football/team/:nameTeam details
GET/api/football/team/:name/playersTeam players
GET/api/football/team/:name/coachTeam coach
GET/api/football/team/:name/statsTeam match stats
GET/api/football/fixturesFixtures
GET/api/football/newsFootball news
GET/api/football/standings/:competitionStandings
GET/api/football/form/:team/:competitionTeam form
GET/api/football/history/:home/:away/:competitionHistorical stats

OrientVirtualFootball endpoints

MethodPathDescription
GET/api/virtual/leaguesList all leagues
POST/api/virtual/simulateSimulate a virtual match
GET/api/virtual/historyMatch history

OrientBank endpoints

MethodPathDescription
POST/api/bank/chargesInitialize a payment (idempotent by reference)
GET/api/bank/charges/:referenceVerify a payment — source of truth
GET/api/bank/charges?limit=20&status=successfulList recent charges for the key
GET/api/bank/accountSettlement account, balance, pending settlement
POST/api/bank/transfersSend a payout to a Nigerian bank account
GET/api/bank/transfers/:referenceTransfer status
GET/api/bank/banksNigerian bank list with NIP codes
POST/api/bank/resolve-accountName enquiry for account_number + bank_code
POST/api/bank/charges/:reference/completeTest mode only — force a charge successful

Base URL https://api.orientapihub.com. Server-to-server only — no CORS headers are returned. Authenticate with x-api-key: ob_... (or Authorization: Bearer). Amounts are in naira (major units). Every error returns { success: false, error, code }.

curl -X POST https://api.orientapihub.com/api/bank/charges \
  -H "x-api-key: ob_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 4000,
    "currency": "NGN",
    "reference": "mutate_abc123",
    "customer": { "email": "x@y.com", "name": "Jane", "phone": "080..." },
    "description": "MutateAds Standard plan",
    "redirect_url": "https://mutateads.com/pricing?paid=1",
    "metadata": { "plan": "standard" }
  }'

Webhooks

Register a webhook URL per key in Dashboard → OrientBank → Webhooks (or via the API below). Events: charge.successful, charge.failed, transfer.successful, transfer.failed. Non-2xx responses are retried up to 5 times with backoff.

  • Header: x-orientbank-signature
  • Value: plain lowercase hex — no sha256= prefix. This is locked and stable.
  • Computed as HMAC_SHA256(secret, rawRequestBodyBytes) — the exact bytes we send, never re-serialized JSON.
  • x-orientbank-timestamp (unix seconds) is sent but is not part of the signed string. The signed payload is the raw body only.
  • During a 24h rotation grace window we also send x-orientbank-signature-prev, signed with the previous secret.
  • Test mode uses the same secret as live — mode is indicated by data.mode in the payload.

Body shape:

POST https://mutateads.com/api/public/orientbank-webhook
x-orientbank-signature: 9f1c...            // hex, HMAC-SHA256 of the raw body
x-orientbank-timestamp: 1786393468         // unix seconds, NOT signed
x-orientbank-event: charge.successful

{
  "event": "payment.confirmed",            // legacy name, kept for compatibility
  "type": "charge.successful",             // canonical event name
  "created_at": "2026-08-11T03:40:00.000Z",
  "data": {
    "reference": "mutate_abc123",
    "status": "successful",
    "amount": 4000,
    "amount_settled": 3940,
    "currency": "NGN",
    "fee": 60,
    "paid_at": "2026-08-11T03:39:58.000Z",
    "customer": { "email": "x@y.com", "name": "Jane", "phone": "080..." },
    "metadata": { "plan": "standard" },
    "mode": "live"
  }
}

Manage the endpoint and secret programmatically:

# read the current endpoint + secret (created on first read)
curl https://api.orientapihub.com/api/bank/webhook -H "x-api-key: ob_YOUR_KEY"
# -> { "success": true, "url": "...", "secret": "obwh_...", "test_mode": false }

# set the endpoint
curl -X POST https://api.orientapihub.com/api/bank/webhook \
  -H "x-api-key: ob_YOUR_KEY" -H "Content-Type: application/json" \
  -d '{"url":"https://mutateads.com/api/public/orientbank-webhook"}'

# rotate the secret (old secret stays valid for 24h)
curl -X POST https://api.orientapihub.com/api/bank/webhook/rotate \
  -H "x-api-key: ob_YOUR_KEY"

Node / TypeScript verification:

import { createHmac, timingSafeEqual } from "crypto";

export function verifyOrientBank(rawBody: string, header: string | null, secret: string) {
  if (!header) return false;
  const expected = createHmac("sha256", secret).update(rawBody, "utf8").digest("hex");
  const a = Buffer.from(header.trim(), "utf8");
  const b = Buffer.from(expected, "utf8");
  return a.length === b.length && timingSafeEqual(a, b);
}

// Next.js / Lovable route handler — read the RAW body, never req.json()
export async function POST(req: Request) {
  const raw = await req.text();
  const sig = req.headers.get("x-orientbank-signature");
  const prev = req.headers.get("x-orientbank-signature-prev"); // set during 24h rotation grace

  const ok =
    verifyOrientBank(raw, sig, process.env.ORIENTBANK_WEBHOOK_SECRET!) ||
    verifyOrientBank(raw, prev, process.env.ORIENTBANK_WEBHOOK_SECRET_OLD ?? "");
  if (!ok) return new Response("invalid signature", { status: 401 });

  const { type, data } = JSON.parse(raw);
  if (type === "charge.successful") {
    // credit the user: data.reference, data.amount, data.amount_settled, data.metadata
  }
  return new Response("ok");
}

Test mode

Toggle test mode on a key in the dashboard, then force any charge successful with POST /api/bank/charges/:reference/complete — no real money moves and the webhook still fires.

Error codes

  • 401 — Missing or invalid x-api-key header.
  • 402 — Insufficient credits.
  • 429 — Rate limit exceeded.
  • 500 — Upstream error.