v1.0 · Base URL: https://data.kashify.com.ng

Kashify API Documentation

Integrate airtime, data, and bill payment services into your application. This documentation covers the public REST API endpoints for transactions, service purchases, and catalog lookups.

Base URL https://data.kashify.com.ng/api/v1/public
Format JSON (application/json)
Rate Limit 60 requests/min

Authentication

All API requests require an API key passed as a Bearer token in the Authorization header. Generate your API key from the Kashify dashboard under Settings → Profile.

Security note: Your API key is shown only once upon generation. Store it securely. Unscoped keys have read-only access — you must explicitly grant write scopes for purchase endpoints.
Header Format
Authorization: Bearer YOUR_API_KEY_HERE
Example Request
curl -X GET https://data.kashify.com.ng/api/v1/public/balance \
  -H "Authorization: Bearer ksf_9f8e7d6c5b4a3210..." \
  -H "Accept: application/json"

Balance

Retrieve the wallet balance for the authenticated subscriber.

GET /api/v1/public/balance API Key Required

Returns the main wallet balance and referral balance for the authenticated account.

This endpoint does not require a request body. It is a read-only GET request.
curl -X GET "https://data.kashify.com.ng/api/v1/public/balance" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
const response = await fetch("https://data.kashify.com.ng/api/v1/public/balance", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Accept": "application/json"
  }
});

const data = await response.json();
import requests

response = requests.get(
    "https://data.kashify.com.ng/api/v1/public/balance",
    headers={
        "Authorization": "Bearer YOUR_API_KEY",
        "Accept": "application/json"
    }
)

data = response.json()
$client = new GuzzleHttp\Client();

$response = $client->get(
    "https://data.kashify.com.ng/api/v1/public/balance",
    ["headers" => [
        "Authorization" => "Bearer YOUR_API_KEY",
        "Accept" => "application/json"
    ]]
);

$data = json_decode($response->getBody(), true);
200 Success Response
{
  "success": true,
  "message": "Balance retrieved successfully",
  "data": {
    "wallet_balance": "10000.00",
    "referral_balance": "500.00",
    "currency": "NGN"
  },
  "meta": {
    "timestamp": "2026-06-20T16:34:43+00:00",
    "request_id": "70eed8f1-6a65-4032-9e8a-620325b95aed"
  }
}

Transactions

Query transaction history and details for the authenticated account.

GET /api/v1/public/transactions API Key Required

Returns a paginated list of transactions with optional filtering by status, service, and date range.

Query Parameters

Field Type Required Description
status integer Optional Filter by status: 0 = Success, 1 = Failed, 2 = Pending (Alpha), 5 = Pending
service string Optional Filter by service name (e.g. "Airtime", "Data")
date_from date Optional Start date filter (ISO 8601 format)
date_to date Optional End date filter. Must be after or equal to date_from
page integer Optional Page number (default: 1)
per_page integer Optional Items per page, max 100 (default: 15)
curl -X GET "https://data.kashify.com.ng/api/v1/public/transactions?status=0&page=1&per_page=15" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
const params = new URLSearchParams({
  status: "0",
  page: "1",
  per_page: "15"
});

const response = await fetch(
  `https://data.kashify.com.ng/api/v1/public/transactions?${params}`,
  {
    headers: {
      "Authorization": "Bearer YOUR_API_KEY",
      "Accept": "application/json"
    }
  }
);

const data = await response.json();
import requests

response = requests.get(
    "https://data.kashify.com.ng/api/v1/public/transactions",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    params={"status": 0, "page": 1, "per_page": 15}
)

data = response.json()
$client = new GuzzleHttp\Client();

$response = $client->get(
    "https://data.kashify.com.ng/api/v1/public/transactions",
    ["query" => [
        "status" => 0,
        "page" => 1,
        "per_page" => 15
    ], "headers" => [
        "Authorization" => "Bearer YOUR_API_KEY"
    ]]
);

$data = json_decode($response->getBody(), true);
200 Success Response
{
  "success": true,
  "message": "Transactions retrieved successfully",
  "data": [
    {
      "transaction_reference": "TXN-20260620-ABC123",
      "customer_reference": "08123456789",
      "external_reference": "VT-9f8e7d6c",
      "service_name": "Airtime",
      "service_description": "MTN N500 Airtime",
      "amount": "500.00",
      "status": 0,
      "status_label": "Success",
      "date": "2026-06-20T10:30:00+00:00"
    }
  ],
  "meta": {
    "timestamp": "2026-06-20T16:34:43+00:00",
    "request_id": "daef4517-0ab5-466b-a9f9-8ced9b57127c",
    "pagination": {
      "current_page": 1,
      "last_page": 5,
      "per_page": 15,
      "total": 75
    }
  }
}
GET /api/v1/public/transactions/{transref} API Key Required

Retrieve full details for a specific transaction using its unique reference.

Path Parameters

Field Type Required Description
transref string Required The unique transaction reference (e.g. TXN-20260620-ABC123)
curl -X GET "https://data.kashify.com.ng/api/v1/public/transactions/TXN-20260620-ABC123" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
const transref = "TXN-20260620-ABC123";

const response = await fetch(
  `https://data.kashify.com.ng/api/v1/public/transactions/${transref}`,
  {
    headers: {
      "Authorization": "Bearer YOUR_API_KEY",
      "Accept": "application/json"
    }
  }
);

const data = await response.json();
import requests

transref = "TXN-20260620-ABC123"
response = requests.get(
    f"https://data.kashify.com.ng/api/v1/public/transactions/{transref}",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)

data = response.json()
$transref = "TXN-20260620-ABC123";
$client = new GuzzleHttp\Client();

$response = $client->get(
    "https://data.kashify.com.ng/api/v1/public/transactions/{transref}",
    ["headers" => [
        "Authorization" => "Bearer YOUR_API_KEY"
    ]]
);

$data = json_decode($response->getBody(), true);
200 Success Response
{
  "success": true,
  "message": "Transaction details retrieved successfully",
  "data": {
    "transaction_reference": "TXN-20260620-ABC123",
    "customer_reference": "08123456789",
    "external_reference": "VT-9f8e7d6c",
    "service_name": "Airtime",
    "service_description": "MTN N500 Airtime",
    "amount": "500.00",
    "status": 0,
    "status_label": "Success",
    "date": "2026-06-20T10:30:00+00:00"
  },
  "meta": {
    "timestamp": "2026-06-20T16:34:43+00:00",
    "request_id": "e69e2033-0982-4124-b6df-d135133d514d"
  }
}
GET /api/v1/public/transactions/{transref}/status API Key Required

Quick lookup for the current status of a transaction. Returns a minimal payload compared to the full transaction endpoint.

curl -X GET "https://data.kashify.com.ng/api/v1/public/transactions/TXN-20260620-ABC123/status" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
const transref = "TXN-20260620-ABC123";

const response = await fetch(
  `https://data.kashify.com.ng/api/v1/public/transactions/${transref}/status`,
  {
    headers: {
      "Authorization": "Bearer YOUR_API_KEY",
      "Accept": "application/json"
    }
  }
);

const data = await response.json();
import requests

transref = "TXN-20260620-ABC123"
response = requests.get(
    f"https://data.kashify.com.ng/api/v1/public/transactions/{transref}/status",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)

data = response.json()
$transref = "TXN-20260620-ABC123";
$client = new GuzzleHttp\Client();

$response = $client->get(
    "https://data.kashify.com.ng/api/v1/public/transactions/{transref}/status",
    ["headers" => [
        "Authorization" => "Bearer YOUR_API_KEY"
    ]]
);

$data = json_decode($response->getBody(), true);
200 Success Response
{
  "success": true,
  "message": "Transaction status retrieved successfully",
  "data": {
    "transaction_reference": "TXN-20260620-ABC123",
    "status": 0,
    "status_label": "Success",
    "date": "2026-06-20T10:30:00+00:00"
  },
  "meta": {
    "timestamp": "2026-06-20T16:34:43+00:00",
    "request_id": "117f9da3-5b7d-49e1-88b9-dc07a780d45f"
  }
}

Purchase Airtime

Buy airtime for any supported network. Requires a write-scoped API key and a 4-digit transaction PIN.

POST /api/v1/public/services/airtime API Key Required

Purchases airtime for the specified phone number. The amount is debited from the authenticated subscriber's wallet.

Request Body (JSON)

Field Type Required Description
network string Required Network provider ID. Use GET /catalog/networks to list available networks.
amount numeric Required Amount in Naira. Must be within provider limits.
phone string Required 11-digit phone number (e.g. 08123456789)
airtime_type string Required Delivery method: VTU, Share And Sell, Momo, or Awoof
ref string Required Unique idempotency reference for this transaction
pin string Required 4-digit transaction PIN (e.g. 1234)
ported_number string Optional "true" or "false". Defaults to "false"
Important: The pin field is your 4-digit transaction PIN, not your API key. It authorizes the financial transaction and is required on all purchase endpoints.
curl -X POST "https://data.kashify.com.ng/api/v1/public/services/airtime" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "network": "mtn",
    "amount": 500,
    "phone": "08123456789",
    "airtime_type": "VTU",
    "ref": "unique-ref-12345",
    "pin": "1234"
  }'
const response = await fetch("https://data.kashify.com.ng/api/v1/public/services/airtime", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
    "Accept": "application/json"
  },
  body: JSON.stringify({
    network: "mtn",
    amount: 500,
    phone: "08123456789",
    airtime_type: "VTU",
    ref: "unique-ref-12345",
    pin: "1234"
  })
});

const data = await response.json();
import requests

response = requests.post(
    "https://data.kashify.com.ng/api/v1/public/services/airtime",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={
        "network": "mtn",
        "amount": 500,
        "phone": "08123456789",
        "airtime_type": "VTU",
        "ref": "unique-ref-12345",
        "pin": "1234"
    }
)

data = response.json()
$client = new GuzzleHttp\Client();

$response = $client->post(
    "https://data.kashify.com.ng/api/v1/public/services/airtime",
    [
        "headers" => [
            "Authorization" => "Bearer YOUR_API_KEY",
        ],
        "json" => [
            "network" => "mtn",
            "amount" => 500,
            "phone" => "08123456789",
            "airtime_type" => "VTU",
            "ref" => "unique-ref-12345",
            "pin" => "1234",
        ],
    ]
);

$data = json_decode($response->getBody(), true);
200 Success Response
{
  "success": true,
  "message": "Transaction successful",
  "data": {
    "transaction_reference": "TXN-20260620-AIR789",
    "status": 0,
    "status_label": "Success",
    "amount_kobo": 50000,
    "amount_naira": "500.00",
    "service_name": "Airtime",
    "external_reference": "VT-9f8e7d6c"
  },
  "meta": {
    "timestamp": "2026-06-20T16:34:43+00:00",
    "request_id": "89d34886-fa40-4f7f-8205-a4db1c8d1599"
  }
}

Purchase Data

Buy a data bundle for any supported network. Requires a write-scoped API key and a 4-digit transaction PIN.

POST /api/v1/public/services/data API Key Required

Purchases a data bundle for the specified phone number. Use GET /catalog/data-plans to retrieve available plans and their IDs.

Request Body (JSON)

Field Type Required Description
network string Required Network provider ID. Use GET /catalog/networks to list available networks.
data_plan integer Required Internal plan ID. Use GET /catalog/data-plans to retrieve valid plan IDs.
phone string Required 11-digit phone number (e.g. 08123456789)
ref string Required Unique idempotency reference for this transaction
pin string Required 4-digit transaction PIN (e.g. 1234)
plan integer Optional Legacy alias for data_plan. Normalized automatically.
mobile_number string Optional Legacy alias for phone. Normalized automatically.
ported_number string Optional "true" or "false". Defaults to "false"
curl -X POST "https://data.kashify.com.ng/api/v1/public/services/data" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "network": "mtn",
    "data_plan": 16,
    "phone": "08123456789",
    "ref": "unique-ref-67890",
    "pin": "1234"
  }'
const response = await fetch("https://data.kashify.com.ng/api/v1/public/services/data", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
    "Accept": "application/json"
  },
  body: JSON.stringify({
    network: "mtn",
    data_plan: 16,
    phone: "08123456789",
    ref: "unique-ref-67890",
    pin: "1234"
  })
});

const data = await response.json();
import requests

response = requests.post(
    "https://data.kashify.com.ng/api/v1/public/services/data",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={
        "network": "mtn",
        "data_plan": 16,
        "phone": "08123456789",
        "ref": "unique-ref-67890",
        "pin": "1234"
    }
)

data = response.json()
$client = new GuzzleHttp\Client();

$response = $client->post(
    "https://data.kashify.com.ng/api/v1/public/services/data",
    [
        "headers" => [
            "Authorization" => "Bearer YOUR_API_KEY",
        ],
        "json" => [
            "network" => "mtn",
            "data_plan" => 16,
            "phone" => "08123456789",
            "ref" => "unique-ref-67890",
            "pin" => "1234",
        ],
    ]
);

$data = json_decode($response->getBody(), true);
200 Success Response
{
  "success": true,
  "message": "Transaction successful",
  "data": {
    "transaction_reference": "TXN-20260620-DAT456",
    "status": 0,
    "status_label": "Success",
    "amount_kobo": 150000,
    "amount_naira": "1500.00",
    "service_name": "Data",
    "external_reference": "VT-3a4b5c6d"
  },
  "meta": {
    "timestamp": "2026-06-20T16:34:43+00:00",
    "request_id": "c6eadc7e-bd98-465e-aafb-12821bdd3727"
  }
}

Catalog

Look up available networks and data plans before making a purchase.

GET /api/v1/public/catalog/networks API Key Required

Returns all supported network providers with their IDs. Use the id value as the network parameter in airtime and data purchase requests.

curl -X GET "https://data.kashify.com.ng/api/v1/public/catalog/networks" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
const response = await fetch("https://data.kashify.com.ng/api/v1/public/catalog/networks", {
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Accept": "application/json"
  }
});

const data = await response.json();
import requests

response = requests.get(
    "https://data.kashify.com.ng/api/v1/public/catalog/networks",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)

data = response.json()
$client = new GuzzleHttp\Client();

$response = $client->get(
    "https://data.kashify.com.ng/api/v1/public/catalog/networks",
    ["headers" => [
        "Authorization" => "Bearer YOUR_API_KEY"
    ]]
);

$data = json_decode($response->getBody(), true);
200 Success Response
{
  "success": true,
  "message": "Networks retrieved successfully",
  "data": [
    { "id": "mtn", "name": "MTN", "logo": "https://..." },
    { "id": "airtel", "name": "Airtel", "logo": "https://..." },
    { "id": "glo", "name": "Glo", "logo": "https://..." },
    { "id": "9mobile", "name": "9mobile", "logo": "https://..." }
  ],
  "meta": {
    "timestamp": "2026-06-20T16:34:43+00:00",
    "request_id": "bace5dc9-4b2b-4184-9936-4741fb4f57c2"
  }
}
GET /api/v1/public/catalog/data-plans API Key Required

Returns available data plans. Optionally filter by network and plan type.

Query Parameters

Field Type Required Description
network string Optional Filter by network ID (e.g. mtn, airtel)
type string Optional Filter by plan type
curl -X GET "https://data.kashify.com.ng/api/v1/public/catalog/data-plans?network=mtn" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
const params = new URLSearchParams({ network: "mtn" });

const response = await fetch(
  `https://data.kashify.com.ng/api/v1/public/catalog/data-plans?${params}`,
  {
    headers: {
      "Authorization": "Bearer YOUR_API_KEY",
      "Accept": "application/json"
    }
  }
);

const data = await response.json();
import requests

response = requests.get(
    "https://data.kashify.com.ng/api/v1/public/catalog/data-plans",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    params={"network": "mtn"}
)

data = response.json()
$client = new GuzzleHttp\Client();

$response = $client->get(
    "https://data.kashify.com.ng/api/v1/public/catalog/data-plans",
    ["query" => ["network" => "mtn"], "headers" => [
        "Authorization" => "Bearer YOUR_API_KEY"
    ]]
);

$data = json_decode($response->getBody(), true);
200 Success Response
{
  "success": true,
  "message": "Data plans retrieved successfully",
  "data": [
    {
      "id": 16,
      "name": "MTN 1GB",
      "network": "mtn",
      "amount": "1500.00",
      "duration": "30 days",
      "size": "1024 MB"
    },
    {
      "id": 17,
      "name": "MTN 3GB",
      "network": "mtn",
      "amount": "4000.00",
      "duration": "30 days",
      "size": "3072 MB"
    }
  ],
  "meta": {
    "timestamp": "2026-06-20T16:34:43+00:00",
    "request_id": "8db9b2d1-55b4-4cd4-bd50-dc4cd26c149b"
  }
}

Error Responses

The API uses standard HTTP status codes. All error responses follow a consistent JSON structure.

Error Response Format
{
  "success": false,
  "message": "Human-readable error description",
  "error_code": "MACHINE_READABLE_CODE",
  "meta": {
    "timestamp": "2026-06-20T16:34:43+00:00",
    "request_id": "70eed8f1-6a65-4032-9e8a-620325b95aed"
  }
}

HTTP Status Codes

Code Error Code Description
401 INVALID_API_KEY API key is missing, invalid, or expired
401 EXPIRED_API_KEY API key has passed its expiration date
401 SUBSCRIBER_NOT_FOUND No subscriber account linked to this API key
403 INSUFFICIENT_PERMISSIONS API key lacks write scope for this endpoint
422 VALIDATION_ERROR Request body failed validation. Check the message for details
429 RATE_LIMITED Too many requests. Check x-ratelimit-reset header for retry time
401 INVALID_PIN Transaction PIN is incorrect (purchase endpoints only)
422 INSUFFICIENT_BALANCE Wallet balance is too low for this transaction

Kashify API v1 · Built with care in Lagos, Nigeria

© 2026 Kashify. All rights reserved.