SaukiMartSaukiMart Developersv1.0.4 · Production

Architecture & Overview

Single Unified REST Contract

The SaukiMart Developer API standardizes mobile data recharges for MTN, Airtel, Glo, and 9Mobile. Regardless of network carrier, the request schema, status codes, and callback signatures are completely uniform.

Base Production URLhttps://saukimart.com
Sandbox Base URLhttps://saukimart.com/api/v1/test
Data FormatJSON (Content-Type: application/json)
AuthenticationHeader: x-api-key: sm_live_... / sm_test_...
Default Rate Limit90 requests / minute per API key

Quickstart

4 Steps to Integration

Go from registration to live data fulfillment in under 5 minutes.

STEP 11. Get Your Key

Sign up, enable Developer Mode in the dashboard, and copy your live (sm_live_...) or test key.

STEP 22. Query Plans

Call GET /api/v1/data-plans to get wholesale plan codes, validity, and discounted developer rates.

STEP 33. Execute Purchase

Send a POST to /api/v1/purchase-data with the target phone, planCode, network, and idempotencyKey.

STEP 44. Receive Webhook

Optionally register a webhook endpoint to receive real-time completion callbacks.

🤖Explain or generate code with your favorite AI:
Ready to delegate integration?Copy the full API integration prompt with all endpoint specs, error codes, and idempotency rules.
Quickstart Sample · curl
# 1. Fetch available data plans across MTN, Airtel, Glo & 9Mobile
curl -X GET "https://saukimart.com/api/v1/data-plans" \
  -H "x-api-key: sm_live_9a8b7c6d5e4f..."

# 2. Purchase data bundle with idempotency protection
curl -X POST "https://saukimart.com/api/v1/purchase-data" \
  -H "Content-Type: application/json" \
  -H "x-api-key: sm_live_9a8b7c6d5e4f..." \
  -d '{
    "phoneNumber": "08012345678",
    "planCode": 23,
    "network": 1,
    "idempotencyKey": "req_8f19e7a2b"
  }'

Security & Auth

API Key Authentication

All API requests must include your secret API key in the x-api-key HTTP header. Keys are prefixed with sm_live_ for production and sm_test_ for sandbox environments.

HeaderFormatDescription
x-api-keysm_live_<prefix>_<secret>Production key — debits live wallet balance
x-api-keysm_test_<prefix>_<secret>Sandbox key — ₦0 simulated transactions
Content-Typeapplication/jsonRequired for all POST/PUT request bodies
Header Authentication Format
$curl -X GET "https://saukimart.com/api/v1/data-plans" \
-H "x-api-key: sm_live_9a8b7c6d5e4f..."
Error Response — Invalid or Missing Key (401)
401 Unauthorized · application/json
{
  "success": false,
  "error": "A valid API key is required. Pass your key in the x-api-key header.",
  "code": "INVALID_API_KEY",
  "statusCode": 401,
  "requestId": "req_a1b2c3d4"
}

Available Scopes

ScopeGrants Access To
read:plansGET /api/v1/data-plans, GET /api/v1/me, GET /api/v1/wallet/balance
write:purchasesPOST /api/v1/purchase-data
read:transactionsGET /api/v1/transactions, GET /api/v1/transactions/:id

Endpoint 01 · Account

Get User Profile

Returns the authenticated developer's profile details, account status, and API key metadata. Use this endpoint to verify authentication and display user information in your integration dashboard.

GET/api/v1/me
Scope: read:plans
GET /api/v1/me (CURL)
$curl -X GET "https://saukimart.com/api/v1/me" \
-H "x-api-key: sm_live_9a8b7c6d5e4f..."
Example Response Payload (200 OK)
200 OK · application/json
{
  "success": true,
  "version": "2026-04-17",
  "requestId": "req_a1b2c3d4",
  "user": {
    "id": "usr_uuid_12345",
    "firstName": "David",
    "lastName": "Adeleke",
    "phone": "08012345678",
    "isDeveloper": true,
    "developerDiscountPercent": 5,
    "accountNumber": "7821234567",
    "bankName": "SaukiMart (Flutterwave)",
    "phoneVerified": true,
    "phoneVerifiedAt": "2026-06-15T10:30:00Z",
    "createdAt": "2026-05-01T08:00:00Z"
  },
  "environment": "live",
  "keyName": "production-server",
  "scopes": [
    "read:plans",
    "write:purchases",
    "read:transactions"
  ]
}

Parameters & Schema Guide

FieldDescription
user.idstringRequiredUnique user identifier (UUID)
user.firstNamestringRequiredDeveloper first name
user.lastNamestringRequiredDeveloper last name
user.phonestringRequired11-digit registered phone number
user.isDeveloperbooleanRequiredWhether developer mode is enabled
user.developerDiscountPercentnumberRequiredWholesale discount rate applied to purchases
user.accountNumberstring | nullVirtual bank account number for wallet funding
user.bankNamestring | nullBank name for the virtual account
user.phoneVerifiedbooleanRequiredPhone verification status
user.createdAtISO 8601RequiredAccount creation timestamp
environmentstringRequiredKey environment — "live" or "test"
scopesstring[]RequiredPermissions granted to the API key

Endpoint 02 · Account

Fetch Wallet Balance

Returns the current wallet balance for the authenticated developer. Use this before executing purchases to verify sufficient funds and prevent 402 INSUFFICIENT_FUNDS errors.

GET/api/v1/wallet/balance
Scope: read:plans
GET /api/v1/wallet/balance (CURL)
$curl -X GET "https://saukimart.com/api/v1/wallet/balance" \
-H "x-api-key: sm_live_9a8b7c6d5e4f..."
Example Response Payload (200 OK)
200 OK · application/json
{
  "success": true,
  "version": "2026-04-17",
  "requestId": "req_e5f6g7h8",
  "wallet": {
    "balance": 125430.5,
    "currency": "NGN",
    "lastUpdated": "2026-08-19T14:30:00Z"
  },
  "environment": "live"
}

Parameters & Schema Guide

FieldDescription
wallet.balancenumberRequiredCurrent wallet balance in NGN (Nigerian Naira)
wallet.currencystringRequiredCurrency code — always "NGN"
wallet.lastUpdatedISO 8601RequiredTimestamp of the last wallet mutation
💡 Developer Integration Tip:
  • Call this endpoint before every purchase to pre-flight check available balance.
  • Fund your wallet via bank transfer to the virtual account number shown in GET /api/v1/me.

Plan Catalog

Current Wholesale & Developer Rates

Updated in real-time. Pass the numeric planCode into your API purchase calls.

GET

MTN

CODESIZEDAYSPRICE
201500MB30d₦284.05
2021GBPopular30d₦407.55
2032GB30d₦759.05
2043GB30d₦1,234.05
2055GB30d₦1,709.05
2067GB30d₦2,374.05

GLO

CODESIZEDAYSPRICE
301200MB30d₦94.05
302500MB30d₦189.05
3031GBPopular30d₦379.05
3042GB30d₦759.05
3053GB30d₦1,139.05
3065GB30d₦1,899.05

AIRTEL

CODESIZEDAYSPRICE
401500MB7d₦521.55
4021GBPopular30d₦722.00
4032GB30d₦1,358.50
4043GB30d₦2,108.05
4054GB30d₦2,488.05
40610GB30d₦3,704.05

Endpoint 03 · Core Data API

Fetch Available Data Plans

Returns the active mobile data bundle catalog across all supported Nigerian carriers (MTN, Airtel, Glo, 9Mobile) with real-time wholesale developer pricing calculated for your account.

GET/api/v1/data-plans
Scope: read:plans
GET /api/v1/data-plans (CURL)
$curl -X GET "https://saukimart.com/api/v1/data-plans" \
-H "x-api-key: sm_live_9a8b7c6d5e4f..."
Example Response Payload (200 OK)
200 OK · application/json
{
  "success": true,
  "version": "2026-04-17",
  "requestId": "req_dp_10293847",
  "discountPercent": 5,
  "plans": [
    {
      "code": 23,
      "network": "MTN",
      "networkId": 1,
      "planId": 201,
      "dataSize": "1GB",
      "validity": "30 Days",
      "appPrice": 350,
      "developerPrice": 332.5
    },
    {
      "code": 24,
      "network": "MTN",
      "networkId": 1,
      "planId": 202,
      "dataSize": "2GB",
      "validity": "30 Days",
      "appPrice": 700,
      "developerPrice": 665
    },
    {
      "code": 31,
      "network": "GLO",
      "networkId": 2,
      "planId": 301,
      "dataSize": "1GB",
      "validity": "30 Days",
      "appPrice": 399,
      "developerPrice": 379.05
    },
    {
      "code": 41,
      "network": "AIRTEL",
      "networkId": 4,
      "planId": 401,
      "dataSize": "1GB",
      "validity": "30 Days",
      "appPrice": 760,
      "developerPrice": 722
    }
  ]
}

Parameters & Schema Guide

FieldDescription
codeintegerRequiredUnique numeric identifier of the plan to pass into /purchase-data
networkstringRequiredTelecom carrier name (MTN, AIRTEL, GLO, 9MOBILE)
networkIdintegerRequiredNumeric carrier ID: 1=MTN, 2=Glo, 3=9Mobile, 4=Airtel
dataSizestringRequiredBundle data allowance (e.g. 500MB, 1GB, 2GB, 5GB)
validitystringRequiredBundle validity duration (e.g. "30 Days", "7 Days")
developerPricenumberRequiredWholesale cost in NGN deducted from your wallet balance
appPricenumberRequiredStandard retail price in NGN before developer discount
💡 Developer Integration Tip:
  • Cache the plan catalog locally for 5–15 minutes to reduce API latency in your checkout flows.
  • Always use the integer "code" field as the plan identifier in your purchase requests.

Endpoint 04 · Core Data API

Purchase Mobile Data Bundle

Executes instant, automated data delivery to the specified Nigerian phone number. Guaranteed atomic wallet deduction with idempotency protection to eliminate double debit risks.

POST/api/v1/purchase-data
Scope: write:purchases
POST /api/v1/purchase-data (CURL)
$curl -X POST "https://saukimart.com/api/v1/purchase-data" \
-H "Content-Type: application/json" \
-H "x-api-key: sm_live_9a8b7c6d5e4f..." \
-d '{
"phoneNumber": "08012345678",
"planCode": 23,
"network": 1,
"idempotencyKey": "order_uuid_98f12a4c"
}'
Example Response Payload (200 OK)
200 OK · application/json
{
  "success": true,
  "status": "success",
  "transactionId": "tx_a8f9c0e2_1948",
  "idempotencyKey": "order_uuid_98f12a4c",
  "data": {
    "planCode": 23,
    "network": "MTN",
    "phoneNumber": "08012345678",
    "dataSize": "1GB",
    "deliveryReference": "AMG-987654321"
  },
  "developerPrice": 332.5,
  "newBalance": 125098,
  "timestamp": "2026-08-21T14:30:00Z"
}

Parameters & Schema Guide

FieldDescription
phoneNumberstringRequired11-digit recipient Nigerian phone number (e.g. "08012345678")
planCodeintegerRequiredBundle plan code obtained from GET /api/v1/data-plans
networkintegerRequiredNumeric carrier ID: 1 for MTN, 2 for Glo, 3 for 9Mobile, 4 for Airtel
idempotencyKeystringRequiredUnique UUIDv4 per customer order to prevent duplicate charges
💡 Developer Integration Tip:
  • Always supply a unique idempotencyKey per customer order. If network timeouts occur, retry with the EXACT SAME idempotencyKey.
  • Sandbox testing: Recipient number 08012345678 will simulate instant delivery with ₦0 wallet debit.

Endpoint 05 · Reconciliation

Query Transaction History

Fetch paginated developer transaction logs, carrier delivery receipts, and reconciliation records. Filter by status or idempotency key.

GET/api/v1/transactions
Scope: read:transactions
GET /api/v1/transactions (CURL)
$curl -X GET "https://saukimart.com/api/v1/transactions?limit=20&status=success" \
-H "x-api-key: sm_live_9a8b7c6d5e4f..."
Example Response Payload (200 OK)
200 OK · application/json
{
  "success": true,
  "version": "2026-04-17",
  "requestId": "req_tx_query_9812",
  "transactions": [
    {
      "id": "dev_tx_01",
      "transactionId": "tx_a8f9c0e2_1948",
      "status": "success",
      "phoneNumber": "08012345678",
      "network": "MTN",
      "planCode": "1-201",
      "planName": "MTN 1GB (30 Days)",
      "developerPrice": 332.5,
      "appPrice": 350,
      "idempotencyKey": "order_uuid_98f12a4c",
      "amigoReference": "AMG-987654321",
      "createdAt": "2026-08-21T14:30:00Z"
    }
  ]
}

Parameters & Schema Guide

FieldDescription
limitquery integerMaximum records to return (default: 50, max: 200)
statusquery stringFilter by status: "success", "pending", "failed"
idempotencyKeyquery stringFilter by original request idempotency key
transactionIdquery stringFilter by specific SaukiMart transaction ID
💡 Developer Integration Tip:
  • Use query filtering to automate end-of-day reconciliation with your accounting ledgers.

Endpoint 06 · Reconciliation

Query Individual Transaction

Look up a single transaction by its SaukiMart Transaction ID, Internal DB UUID, or your original Idempotency Key. Critical for timeout recovery and polling pending fulfillment states.

GET/api/v1/transactions/:id
Scope: read:transactions
GET /api/v1/transactions/:id (CURL)
$curl -X GET "https://saukimart.com/api/v1/transactions/order_uuid_98f12a4c" \
-H "x-api-key: sm_live_9a8b7c6d5e4f..."
Example Response Payload (200 OK)
200 OK · application/json
{
  "success": true,
  "version": "2026-04-17",
  "requestId": "req_single_tx_5544",
  "transaction": {
    "id": "dev_tx_uuid_1029",
    "transactionId": "tx_a8f9c0e2_1948",
    "status": "success",
    "transactionStatus": "COMPLETED",
    "phoneNumber": "08012345678",
    "network": "MTN",
    "planCode": "1-201",
    "planName": "MTN 1GB (30 Days)",
    "developerPrice": 332.5,
    "appPrice": 350,
    "idempotencyKey": "order_uuid_98f12a4c",
    "amigoReference": "AMG-987654321",
    "rawStatus": "SUCCESSFUL",
    "endpoint": "/api/v1/purchase-data",
    "message": "Data bundle successfully delivered to recipient",
    "createdAt": "2026-08-21T14:30:00Z"
  },
  "environment": "live"
}

Parameters & Schema Guide

FieldDescription
:id (path)stringRequiredSaukiMart Transaction ID, Internal UUID, or your request idempotencyKey
transaction.statusstringRequiredStandardized delivery status: "success", "pending", or "failed"
transaction.amigoReferencestring | nullUpstream telecom carrier reference code
transaction.developerPricenumberRequiredExact amount in NGN deducted for this transaction
transaction.idempotencyKeystring | nullOriginal client idempotency key
💡 Developer Integration Tip:
  • If a POST /purchase-data call times out on your end, do NOT immediately retry with a new key. Call this endpoint with your idempotencyKey to inspect whether the initial purchase succeeded.
  • If the status is "pending", poll this endpoint with exponential backoff (e.g. 5s, 15s, 30s) or rely on incoming webhooks.

Webhooks & Events

Real-time Delivery Webhooks

Instead of polling the API, configure an HTTPS webhook URL in your developer dashboard. SaukiMart sends automated HTTP POST event dispatches whenever asynchronous telecom fulfillment completes or fails.

Incoming Webhook POST Event Payload
POST /api/webhooks/saukimart · application/json
{
  "event": "developer.purchase.completed",
  "transactionId": "tx_a8f9c0e2_1948",
  "status": "success",
  "planCode": 23,
  "network": "MTN",
  "phoneNumber": "08012345678",
  "dataSize": "1GB",
  "amount": 332.5,
  "idempotencyKey": "order_uuid_98f12a4c",
  "timestamp": "2026-08-21T14:30:05.000Z"
}

Webhook Event Catalog

EventTrigger ConditionExpected Action
developer.purchase.completedCarrier confirmed data bundle delivered to recipientMark order completed in your system and notify end-user
developer.purchase.failedCarrier rejected fulfillment or invalid numberRefund end-user or prompt to re-enter phone number
developer.wallet.low_balanceDeveloper wallet balance fell below threshold (₦5,000)Alert finance team to fund developer wallet
🔒 Webhook Signature Verification

If you configure a webhook signing secret in your dashboard, every webhook dispatch includes the X-SaukiMart-Webhook-Secret header. Verify this header matches your secret to protect against replay attacks.

// Express / Node.js Webhook Handler
app.post('/api/webhooks/saukimart', (req, res) => {
  const secret = req.headers['x-saukimart-webhook-secret'];
  if (secret !== process.env.SAUKIMART_WEBHOOK_SECRET) {
    return res.status(401).send('Unauthorized');
  }

  const { event, transactionId, status } = req.body;
  if (event === 'developer.purchase.completed') {
    // Fulfill customer order in your database
  }

  res.status(200).json({ received: true });
});

Reference & Diagnostics

HTTP Status Codes & Error Matrix

Every API failure returns a standard JSON error payload containing machine-readable error codes, human-friendly diagnostics, and an idempotent request tracking ID.

Standard Failure Response Schema
402 Payment Required · application/json
{
  "success": false,
  "error": "Insufficient wallet balance to fulfill purchase",
  "code": "INSUFFICIENT_FUNDS",
  "statusCode": 402,
  "requestId": "req_98f12a",
  "timestamp": "2026-08-21T14:30:00.000Z"
}
HTTP StatusError CodeDescriptionDeveloper Action
200 OKSUCCESSPurchase executed and bundle vended successfully.Parse transactionId and store confirmation in your database.
400 Bad RequestINVALID_PARAMSMissing required fields (phoneNumber, planCode, or network).Ensure request body satisfies schema requirements.
401 UnauthorizedINVALID_API_KEYx-api-key header is missing, expired, or invalid.Verify your key credentials in the Developer Dashboard.
402 Payment RequiredINSUFFICIENT_FUNDSWallet balance is lower than developer wholesale price.Fund your Sauki developer wallet via bank transfer.
404 Not FoundPLAN_NOT_FOUNDThe specified planCode does not exist for this network.Query GET /api/v1/data-plans for active bundles.
404 Not FoundTRANSACTION_NOT_FOUNDNo transaction matching the provided ID or idempotency key.Check reference string or verify transaction belongs to this key.
409 ConflictDUPLICATE_IDEMPOTENCY_KEYA purchase with this idempotencyKey was already processed.Query GET /api/v1/transactions/:id to inspect original status.
422 UnprocessableINVALID_PHONE_NUMBERRecipient phone number is invalid (must be 11-digit Nigerian MSISDN).Validate 11-digit phone format before sending.
429 Too Many RequestsRATE_LIMIT_EXCEEDEDExceeded 90 requests/minute throughput.Read Retry-After header and apply exponential backoff.
502 Bad GatewayPROVIDER_DOWNUpstream telecom carrier switch is temporarily unreachable.Retry with the EXACT SAME idempotencyKey after a delay.
503 UnavailableMAINTENANCECarrier bundle network is undergoing scheduled maintenance.Check carrier status and retry during operational windows.

Architecture Reference

Rate Limiting & Idempotency Rules

SaukiMart enforces production-grade reliability primitives to guarantee zero double debits and maintain 99.99% infrastructure availability.

🔒 Zero Double Debit Guarantee

Every POST /api/v1/purchase-data request requires an idempotencyKey. If your server encounters a network timeout or 502 Bad Gateway, retrying with the exact same key guarantees your wallet is charged at most once.

⚡ Rate Limits & Response Headers

Production keys are provisioned for 90 requests/minute (custom limits up to 600 req/min available for enterprise). Every response returns:

  • X-RateLimit-Limit: Max requests allowed per window
  • X-RateLimit-Remaining: Remaining requests in current window
  • X-RateLimit-Reset: UTC ISO timestamp when window resets

SDKs & Resources

Developer SDKs & OpenAPI Specification

Accelerate your telecom integration with official code samples, OpenAPI 3.0 schemas, and Postman collections.

OpenAPI 3.0 Schema

Complete machine-readable JSON OpenAPI specification for code generators and Swagger UI.

View OpenAPI Spec
cURL & REST

Direct HTTP calls from any programming language or command-line environment.

View Samples
Node.js / TypeScript

Native Fetch, Axios, or HTTP client integrations with complete TypeScript types.

View Code
Python / Django / FastAPI

Requests and HTTPX client code snippets for instant backend vending.

View Code