This guide gets you from zero to a working Plustive API integration in under 15 minutes. You'll get a key, fund a wallet, fetch the plan catalog, make your first data purchase, and wire up idempotency so retries are always safe. Every example is a live curl command against https://api.plustiveimpact.com. All amounts are in integer kobo (₦1 = 100 kobo).
Before you start
You need three things:
- A Plustive account — create one at app.plustiveimpact.com.
- Your API key — available in the dashboard under API & keys. It looks like
pk_live_…. - A funded wallet — transfer your starting float to the dedicated bank account (NUBAN) shown in the dashboard. The balance appears automatically.
Step 1 — Confirm authentication
Start with a read-only call to verify the key works and see your current balance. If you get a 401, the key is wrong or missing.
curl https://api.plustiveimpact.com/api/v1/balance \
-H "Authorization: Bearer pk_live_xxx"
→ { "balance": 50000000, "currency": "NGN" }
# ↑ ₦500,000.00 in koboStep 2 — List the catalog
Data is purchased by plan ID, not a free-form amount. The catalog returns every available plan and the price you pay — your cost. Add your margin on top to set the retail price you show customers.
curl https://api.plustiveimpact.com/api/v1/plans \
-H "Authorization: Bearer pk_live_xxx"
→ [
{ "id": "mtn-1gb-30d", "network": "mtn", "price": 27000 },
{ "id": "glo-2gb-30d", "network": "glo", "price": 48000 },
{ "id": "airt-500mb-7d","network": "airtel", "price": 15000 },
{ "id": "9mob-1gb-30d", "network": "9mobile","price": 29500 }
]
# prices in kobo — mtn-1gb-30d costs you ₦270.00Store the id values in your database. Re-fetch the catalog periodically — prices and plan availability can change.
Step 3 — Make your first purchase
Pass the plan field (the plan ID), the recipient's phone number, and a clientReference you generate. TheclientReference should be your internal order ID — unique per order, persisted before the call.
curl -X POST https://api.plustiveimpact.com/api/v1/data \
-H "Authorization: Bearer pk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"plan": "mtn-1gb-30d",
"phone": "08030000000",
"clientReference": "ord_20260616_001"
}'
→ {
"reference": "PLS-7XKQR4N",
"status": "Success",
"amount": 27000
}A Success response means the bundle has been delivered. A Pending response means it hasn't resolved yet — see Step 5 for how to handle it.
Airtime follows the same shape but uses network and an amount in kobo:
curl -X POST https://api.plustiveimpact.com/api/v1/airtime \
-H "Authorization: Bearer pk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"network": "glo",
"phone": "08100000000",
"amount": 100000,
"clientReference": "ord_20260616_002"
}'
# amount 100000 = ₦1,000.00Step 4 — Safe retries with idempotency
Networks time out. The wrong response to a timeout is to generate a new order — that risks a double debit. The correct response is to retry with the same clientReference. Plustive enforces idempotency: if a reference has already succeeded, the retry returns the original result with no second debit.
# First attempt — network error, unknown whether it succeeded
curl -X POST https://api.plustiveimpact.com/api/v1/data \
-H "Authorization: Bearer pk_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "plan": "mtn-1gb-30d", "phone": "08030000000", "clientReference": "ord_20260616_001" }'
# → connection error
# Safe retry — identical request, identical clientReference
curl -X POST https://api.plustiveimpact.com/api/v1/data \
-H "Authorization: Bearer pk_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "plan": "mtn-1gb-30d", "phone": "08030000000", "clientReference": "ord_20260616_001" }'
# → returns the original transaction, no new debitGenerate clientReference once per order and save it to your database before calling the API. Never generate a new one on retry.Step 5 — Handle Pending and auto-refunds
Some transactions return Pending — the network hasn't confirmed the delivery yet. Plustive monitors these and reconciles them automatically, usually within about a minute. If the delivery ultimately fails, the full debit is refunded to your wallet automatically — no ticket, no manual reversal.
To check the current status of a transaction:
curl https://api.plustiveimpact.com/api/v1/transactions/PLS-7XKQR4N \
-H "Authorization: Bearer pk_live_xxx"
→ { "reference": "PLS-7XKQR4N", "status": "Success", "amount": 27000 }Terminal states are Success, Failed, and Refunded. Act on the terminal state; never act on Pending.
Step 6 — Subscribe to webhooks
Polling is fine for small volume, but webhooks are the right production pattern. Register an HTTPS endpoint in your Plustive dashboard. Plustive will POST a signed payload when any transaction reaches a terminal state:
{
"event": "transaction.completed",
"reference": "PLS-7XKQR4N",
"status": "Success",
"amount": 27000,
"clientReference": "ord_20260616_001",
"timestamp": "2026-06-16T09:14:33Z"
}Verify the signature (using the signing secret in your dashboard) before acting on the payload. Make your handler idempotent — the same event may arrive more than once on retries. See the webhooks integration guide and the webhooks reference for the full signature verification spec.
Integration checklist
- Store
clientReferenceper order before calling the API; reuse on retry. - Treat
Pendingas not-yet-final; update the order only on a terminal state. - Keep all money in integer kobo throughout; convert only for display.
- Verify webhook signatures before trusting payloads.
- Monitor your wallet balance — a zero balance stops fulfilment instantly.
- Re-fetch the plan catalog periodically to catch price or availability changes.