Preview: the API is being built and these endpoints may change

POST/api/v1/airtime

Send airtime

Top up any Nigerian number on MTN, Airtel, Glo or 9mobile.

Routes the top-up through a line that can send it on the network and answers with the final state.

Body

FieldTypeRequiredNotes
product_codestringyesThe network's airtime product: MTN-VTU, AIRTEL-VTU, GLO-VTU or 9MOBILE-VTU. See List plans
amountnumberyesNaira, at most two decimals, within the product's min_amount and max_amount
phone_numberstringyesNigerian number, 08012345678 or +2348012345678. phone is accepted as an alias
client_referencestringnoYour own reference, 1 to 128 characters, unique per mode

Send an Idempotency-Key header with every request. You can also send network (such as mtn) on its own instead of product_code, and the network's airtime product is used.

Waiting for the result

By default the call stays open until the sale is final, up to a limit set by us, and answers 200. If the sale is still on its way when the limit is reached, it answers 202 with the sale as it stands (status not final yet). Add ?wait=0 to get 202 at once and follow the sale by webhook or Get a transaction.

Request

bash
curl https://api.simconnectng.com/api/v1/airtime \
  -H "Authorization: Bearer $SIMCONNECT_KEY" \
  -H "Idempotency-Key: order_1042" \
  -H "Content-Type: application/json" \
  -d '{ "product_code": "MTN-VTU", "amount": 500, "phone_number": "08012345678", "client_reference": "order_1042" }'

Response

json
{
  "success": true,
  "data": {
    "id": "0192f4c1-a7e8-7b6f-9d2c-3e5a7b9d1f30",
    "reference": "txn_0192f4c1a7e84b6f9d2c3e5a7b9d1f30",
    "client_reference": "order_1042",
    "mode": "live",
    "status": "successful",
    "product_code": "MTN-VTU",
    "network": "mtn",
    "service": "airtime",
    "destination": "+234********78",
    "amount": 500.00,
    "price": 2.00,
    "failure_code": null,
    "failure_message": null,
    "created_at": "2026-10-06T12:04:01Z",
    "completed_at": "2026-10-06T12:04:03Z"
  },
  "message": "Transaction successful",
  "code": "OK"
}

A final status is successful or failed. Any other, such as pending, finishes later and you hear about it by webhook. amount is the airtime sent; price is the flat fee your wallet pays for the sale. destination is always masked. The figures shown here are placeholders.

Error

json
{ "success": false, "data": null, "message": "Insufficient wallet balance", "code": "WALLET_INSUFFICIENT_FUNDS" }

Give this to your coding agent

prompt
Read https://simconnectng.com/docs/api/send-airtime.md and implement "Send airtime" (POST /api/v1/airtime) in this project.
Read the API key from the SIMCONNECT_KEY environment variable.
Send an Idempotency-Key derived from our own order id.
Every response is { success, data, message, code }; on an error data is null (or carries data.errors), so branch on code.