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
| Product | Prefix | Base URL | Status |
|---|---|---|---|
| OrientMusic API | om_ | https://api.orientapihub.com/music | Live |
| OrientVideo API | ov_ | https://api.orientapihub.com/video | Live |
| OrientMusicVideo API | omv_ | https://api.orientapihub.com/music-video | Live |
| OrientFootball API | of_ | https://api.orientapihub.com/football | Live |
| OrientEsports API | oe_ | https://api.orientapihub.com/esports | Live |
| OrientVirtualFootball API | ovf_ | https://api.orientapihub.com/virtual-football | Live |
| OrientBank API | ob_ | https://api.orientapihub.com/bank | Live |
| OrientImage API | oi_ | https://api.orientapihub.com/image | Live |
| OrientLLM API | ollm_ | https://api.orientapihub.com/llm | Live |
| OrientVoice API | ovc_ | https://api.orientapihub.com/voice | Live |
| OrientCode API | oc_ | https://api.orientapihub.com/code | Live |
| OrientTranscription API | otr_ | https://api.orientapihub.com/transcription | Live |
| OrientTranslation API | otl_ | https://api.orientapihub.com/translation | Live |
| OrientAfricanLanguages API | oal_ | https://api.orientapihub.com/african-languages | Live |
| OrientScratch API | os_ | https://api.orientapihub.com/scratch | Live |
| OrientLuckyTap API | olt_ | https://api.orientapihub.com/lucky-tap | Live |
| OrientWheel API | ow_ | https://api.orientapihub.com/wheel | Live |
| OrientCrash API | ocr_ | https://api.orientapihub.com/crash | Live |
| Heritage Music Video API | hmv_ | https://api.orientapihub.com/heritage-music-video-app | Live |
| Orient Movie API | omv2_ | https://api.orientapihub.com/orient-movie-api | Live |
| Orient Recharge API | orc_ | https://api.orientapihub.com/orient-recharge-api | Live |
OrientFootball endpoints
| Method | Path | Description |
|---|---|---|
| POST | /api/football | Match prediction |
| POST | /api/football/detailed | Detailed prediction with stats |
| GET | /api/football/competitions | List all competitions |
| GET | /api/football/teams | List all teams |
| GET | /api/football/team/:name | Team details |
| GET | /api/football/team/:name/players | Team players |
| GET | /api/football/team/:name/coach | Team coach |
| GET | /api/football/team/:name/stats | Team match stats |
| GET | /api/football/fixtures | Fixtures |
| GET | /api/football/news | Football news |
| GET | /api/football/standings/:competition | Standings |
| GET | /api/football/form/:team/:competition | Team form |
| GET | /api/football/history/:home/:away/:competition | Historical stats |
OrientVirtualFootball endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/virtual/leagues | List all leagues |
| POST | /api/virtual/simulate | Simulate a virtual match |
| GET | /api/virtual/history | Match history |
OrientBank endpoints
| Method | Path | Description |
|---|---|---|
| POST | /api/bank/charges | Initialize a payment (idempotent by reference) |
| GET | /api/bank/charges/:reference | Verify a payment — source of truth |
| GET | /api/bank/charges?limit=20&status=successful | List recent charges for the key |
| GET | /api/bank/account | Settlement account, balance, pending settlement |
| POST | /api/bank/transfers | Send a payout to a Nigerian bank account |
| GET | /api/bank/transfers/:reference | Transfer status |
| GET | /api/bank/banks | Nigerian bank list with NIP codes |
| POST | /api/bank/resolve-account | Name enquiry for account_number + bank_code |
| POST | /api/bank/charges/:reference/complete | Test 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.modein 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-keyheader. - 402 — Insufficient credits.
- 429 — Rate limit exceeded.
- 500 — Upstream error.