KDA API Logo
API Docs

Get Started

A comprehensive guide to integrating KDA infrastructure into your application.

Welcome to KDA API Docs

Integrate VTU services (Data, Airtime, TV, Electricity, Exam PINs, and more) directly into your application. Our world-class infrastructure delivers lightning-fast, highly reliable, and easily scalable utility vending designed for modern businesses.

Whether you're building a consumer fintech app, a corporate portal, or a specialized vending service, the KDA API provides a secure, flexible, and seamless developer experience from day one.

Base URL

All API requests must be made over HTTPS to:https://kda-turbo-web.vercel.app

The KDA API is organized around REST conventions. It uses predictable, resource-oriented URLs, accepts JSON-encoded request bodies, and returns JSON-encoded responses using standard HTTP verbs and status codes.

Key Concepts

Understanding a few fundamental concepts will make integrating with the KDA API much smoother. Familiarize yourself with these core principles before making your first transaction.

Fundamentals

API Keys

Authenticate every request with a Bearer token. Each key is scoped to either profile (account endpoints) or services (purchase endpoints).

Sandbox Mode

Test keys route to a sandbox that simulates success no real transactions are made.

Plan IDs

Every product has a deterministic kds-* ID. Fetch them via the /plans endpoint for each service.

Idempotency

Include an idempotencyKey (UUID) in purchase requests to prevent duplicate charges.

Versioned Routes

KDA provisions multiple independent routes for its services, giving you the flexibility to integrate one or both. You choose your route dynamically by selecting the corresponding Plan ID (e.g., kds-data-mtn-sme-v1-001).

v1 Route

Backed by primary infrastructure. May offer pricing advantages for certain products or better response times in specific categories.

v2 Route

Backed by secondary infrastructure. Can provide higher uptime for specific providers or alternative products when primary networks are congested.

Available Services

KDA provides a comprehensive suite of utility services designed for seamless integration. From mobile top-ups to bill payments and exam pins, our unified architecture ensures that all endpoints behave predictably. Click on any service below to explore its specific payload requirements and documentation.

Account Endpoints

Beyond core utility vending, the KDA API provides administrative endpoints to help you manage your integration. Use these endpoints to programmatically check your wallet balance, fetch transaction history, or verify your API credentials.

Quick Start

Follow these steps to make your first successful transaction with the KDA API.

Get Your API Keys

Every request to the KDA API requires authentication via a Bearer token. You are issued two keys when you register:

  • Test Key (kds_test_*) — Routes to the sandbox environment. No real money is deducted.
  • Live Key (kds_live_*) — Routes to production. Real transactions are processed.

Each key is assigned a scope when created — choose the one that matches your use case:

  • Profile scope — Grants access to account endpoints (balance, transactions).
  • Services scope — Grants access to service endpoints (purchases, verifications, plans).

An API key can only have one scope. If you need both account and service access, create two separate keys.

Include your key in the Authorization header of every request:

Authorization: Bearer kds_test_YOUR_API_KEY

Verify Your Credentials

Use the /test endpoint to confirm your API key is active, check your environment (Sandbox or Live), and verify connectivity to KDA's servers.

curl -X GET https://kda-turbo-web.vercel.app/api/services/test \
  -H "Authorization: Bearer kds_test_YOUR_API_KEY"
const url = 'https://kda-turbo-web.vercel.app/api/services/test';
const options = {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer kds_test_YOUR_API_KEY'
  }
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
import requests

url = "https://kda-turbo-web.vercel.app/api/services/test"
headers = {
    "Authorization": "Bearer kds_test_YOUR_API_KEY"
}

response = requests.get(url, headers=headers)
print(response.json())
<?php

$ch = curl_init("https://kda-turbo-web.vercel.app/api/services/test");
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer kds_test_YOUR_API_KEY",
    ],
    CURLOPT_RETURNTRANSFER => true,
]);

$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response, true);
print_r($data);
{
  "success": true,
  "message": "API Key is valid and authenticated.",
  "environment": "TEST",
  "user": {
    "id": "cm0z...",
    "email": "developer@example.com"
  },
  "key": {
    "name": "My Sandbox Key",
    "prefix": "kds_test",
    "type": "SANDBOX",
    "scope": "services",
    "enabled": true,
    "remaining": 950,
    "expiresAt": "2027-06-15T14:30:00.000Z",
    "createdAt": "2026-06-15T14:30:00.000Z"
  }
}

Fetch Available Plans

Once verified, fetch the plans for your desired service. Each plan has a unique kds-* ID you'll use when making a purchase.

curl -X GET https://kda-turbo-web.vercel.app/api/services/data/plans \
  -H "Authorization: Bearer kds_test_YOUR_API_KEY"

Browse the service-specific documentation for detailed plan structures:

Make a Purchase

Pick a plan ID from the previous step and send a POST request. Include an idempotencyKey (UUID v4) to prevent duplicate charges.

curl -X POST https://kda-turbo-web.vercel.app/api/services/data \
  -H "Authorization: Bearer kds_test_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "planId": "kds-data-mtn-sme-v1-003",
    "identifier": "08012345678",
    "idempotencyKey": "550e8400-e29b-41d4-a716-446655440000"
  }'

With a test key, you'll receive a simulated success response — no real money is deducted.

{
  "success": true,
  "message": "Data Purchase purchase successful!",
  "transactionId": "KDS-DAT-YRGH1BZA-SN",
  "data": {
    "status": "success",
     .....
  }
}