MsjPay
Developer Center
API Overview

Build on MsjPay

The MsjPay API lets you connect an existing website or app — or build a brand new one — to the same digital services your customers use every day: data, airtime, bills, eSIM and more. Every request is authenticated against your account and settles against your MsjPay wallet balance in real time.

All available endpoints are versioned under /api/v1/ and speak JSON over HTTPS.

Authentication

Every request must include your API key as a Bearer token in the Authorization header. Requests without a valid, active key are rejected with 401 Unauthorized.

Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

Keys never expire on their own and are not tied to any fixed prefix — treat yours like a password. If a key is compromised, regenerate it from your dashboard immediately.

API Credentials

Your API key is generated from your user dashboard after sign-up. It is unique per account, and every request made with it draws directly from that account's wallet balance.

Environments

Production

All requests to /api/v1/ made with a live key are live and move real funds — real airtime/data/etc. is delivered and your real wallet balance is debited.

Sandbox

Same base URL and endpoints as production — swap your live key for a sandbox key and every request is fully simulated: no real money moves, no real provider is ever contacted, and nothing here touches your live wallet or transaction history.

Using the sandbox

  • Generate a sandbox key from your dashboard's Developer API page (login required) — same page as your live key, kept in a separate section.
  • Send it in the same Authorization: Bearer header — which key you send determines the environment, not the URL or any extra parameter.
  • Every sandbox account starts with a simulated ₦1,000,000.00 balance, resettable any time from the dashboard.
  • Purchases (airtime, data, cable TV, electricity, exam pins, betting, recharge cards, data cards, bulk SMS, airtime-to-cash, eSIM, international airtime, gift cards, virtual cards) always succeed instantly — unless the customer identifier you send (phone/meter/smartcard/account number) ends in the 4 digits 0000, which deterministically simulates a provider decline so you can test your failure-handling path too.
  • Sandbox transactions, balance, and virtual cards are entirely separate from your live account's — nothing you do in sandbox is visible on /api/v1/balance, /api/v1/transactions, etc. when called with your live key, and vice versa.
  • No webhook, email, push, or WhatsApp notification is ever sent for sandbox activity.

Available APIs

Endpoints are grouped by what they do. Services shown here reflect what's actually enabled on this account — features not on your plan return 403.

Account & Balance

GET /api/v1/balance
GET /api/v1/dashboard
GET /api/v1/profile
POST /api/v1/update-profile
POST /api/v1/change-pin
POST /api/v1/change-password
GET+POST /api/v1/kyc
GET+POST /api/v1/account-upgrade

Catalog & Pricing

GET /api/v1/catalog
GET /api/v1/pricing
GET /api/v1/site-info

Purchases

POST /api/v1/airtime
POST /api/v1/data
POST /api/v1/cabletv
POST /api/v1/electricity
GET /api/v1/validate-meter
GET /api/v1/validate-cable
POST /api/v1/exam_pin
POST /api/v1/recharge-card
POST /api/v1/data_card
POST /api/v1/bulk_sms
POST /api/v1/betting
POST /api/v1/esim
POST /api/v1/international_airtime
POST /api/v1/a2c
POST /api/v1/smile
POST /api/v1/alpha
POST /api/v1/kirani

Money Movement & Cards

POST /api/v1/fund
GET+POST /api/v1/virtual_accounts
POST /api/v1/bank_transfer
GET+POST /api/v1/beneficiaries
GET+POST /api/v1/virtual_cards

Gift Cards

POST /api/v1/giftcard_buy
POST /api/v1/giftcard_sell

Rewards & Support

GET+POST /api/v1/cashback
POST /api/v1/promo
GET /api/v1/referrals
GET /api/v1/notifications
GET+POST /api/v1/tickets
GET /api/v1/faqs
GET /api/v1/banners
POST /api/v1/push_register

Transaction History

GET /api/v1/transactions
GET /api/v1/receipt
POST /api/v1/data
Request body
{
  "network": "mtn",
  "phone": "08031234567",
  "plan_id": "145"
}

Response 200
{
  "status": "success",
  "data": {
    "reference": "MSJ-9F2K1...",
    "cashback_earned": 0,
    "balance_before": 45250.00,
    "balance_after": 44050.00
  }
}

Transaction Status & Webhooks

Most purchases resolve immediately, returning status: "success" or status: "error" in the same response. Where an upstream provider is slow to confirm, you'll get back status: "pending" with a reference.

There is no outbound webhook subscription for partner integrations yet — poll GET /api/v1/transactions or GET /api/v1/receipt with the reference to resolve a pending transaction's final state. If real-time push callbacks are a requirement for your integration, raise it with the business team.

Error Codes

CodeMeaning
400Bad request — a required field is missing or invalid.
401Missing, invalid, or suspended API key.
403This feature is not enabled on your account/plan.
405Wrong HTTP method for this endpoint (check GET vs. POST).
429Too many requests — you have hit the rate limit.
500Something went wrong on our side. Retry, then contact support if it persists.

API Limits

Purchase-type endpoints (airtime, data, cable TV, electricity, and similar) are rate-limited to 30 requests per 60 seconds per account. Exceeding this returns 429 Too Many Requests — back off and retry after a short delay. Standard daily transaction limits that apply on the website also apply to API purchases on the same account.

Pricing

There is no separate API fee — you transact at your account's own pricing tier (regular, agent, or vendor), the same tiered pricing used on the website. Upgrade your account type to unlock agent/vendor rates. Wallet funding carries no additional fee, subject to applicable terms.

Integration Guide

  1. 1 Create an account and verify your details.
  2. 2 Grab your API key from your dashboard.
  3. 3 Call GET /api/v1/balance to confirm your key works.
  4. 4 Call GET /api/v1/catalog to fetch live, correctly-priced data plans for your tier.
  5. 5 Fund your wallet, then make a test purchase with a small amount.
  6. 6 Go live — point your production integration at the same base URL.

Developer Support

Stuck on an integration, or need a feature enabled for your account? The business team handles developer and partner requests directly.