KDA API Logo
API Docs
Services

Data Cards

Generate printable data PINs for Nigerian networks.

Endpoints

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

Supported Providers

KDA supports data card PIN generation for the following networks:

MTN

MTN

Provider IDs: kds-data-card-mtn-v1

Fetch Plans

curl -X GET https://kda-turbo-web.vercel.app/api/services/data-card/plans \
  -H "Authorization: Bearer kds_test_YOUR_API_KEY"
{
  "success": true,
  "count": 2,
  "data": [
    {
      "id": "kds-data-card-mtn-750mb-v1",
      "label": "750MB",
      "validity": "7 days",
      "salePrice": "410",
      "provider":  "MTN"
    },
    {
      "id": "kds-data-card-mtn-3gb-v1",
      "label": "3GB",
      "validity": "30 days",
      "salePrice": "1350",
      "provider": "MTN"
    }
  ]
}

Fetching without any filter returns all plans. Pass ?id=<planId> to fetch a single plan.

Fetch a single plan by its id:

curl -X GET "https://kda-turbo-web.vercel.app/api/services/data-card/plans?id=kds-data-card-mtn-750mb-v1" \
  -H "Authorization: Bearer kds_test_YOUR_API_KEY"

Anatomy of a Data Card Plan

Each plan object represents a specific data bundle and route combination:

{
  "id": "kds-data-card-mtn-750mb-v1",
  "label": "750MB",
  "validity": "7 days",
  "salePrice": "410",
  "provider": "MTN"
}

Prop

Type

Purchase Flow

Purchase Request

Request Body

Prop

Type

Example

curl -X POST https://kda-turbo-web.vercel.app/api/services/data-card \
  -H "Authorization: Bearer kds_test_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "planId": "kds-data-card-mtn-750mb-v1",
    "quantity": 2,
    "cardName": "Eko Data Card Services",
    "idempotencyKey": "681227cc-2638-49fe-bbe3-d2500cf54767"
  }'
const response = await fetch("https://kda-turbo-web.vercel.app/api/services/data-card", {
  method: "POST",
  headers: {
    "Authorization": "Bearer kds_test_YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    planId: "kds-data-card-mtn-750mb-v1",
    quantity: 2,
    cardName: "Musbahu Data Card",
    idempotencyKey: crypto.randomUUID()
  })
});

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

response = requests.post(
    "https://kda-turbo-web.vercel.app/api/services/data-card",
    headers={
        "Authorization": "Bearer kds_test_YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "planId": "kds-data-card-mtn-750mb-v1",
        "quantity": 2,
        "cardName": "Yellow Communication Services",
        "idempotencyKey": str(uuid.uuid4()),
    },
)

data = response.json()
<?php

$ch = curl_init("https://kda-turbo-web.vercel.app/api/services/data-card");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer kds_test_YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "planId" => "kds-data-card-mtn-750mb-v1",
        "quantity" => 2,
        "cardName" => "Eko Data Card Services",
        "idempotencyKey" => bin2hex(random_bytes(16)),
    ]),
    CURLOPT_RETURNTRANSFER => true,
]);

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

$data = json_decode($response, true);
print_r($data);

Success Response

The response includes the pin and serial in the data object for you to print.

{
  "success": true,
  "message": "Data Card Purchase purchase successful!",
  "transactionId": "KDS-DC-JTYXUD50-SN",
  "data": {
    "amount": 410,
    "label": "750MB",
    "planId": "kds-data-card-mtn-750mb-v1",
    "provider": "MTN",
    "status": "SUCCESS",
    "description": "Data Card Purchase purchase successful!",
    "transactionId": "KDS-DC-JTYXUD50-SN",
    "createdAt": "2026-06-17T12:00:00.000Z",
    "quantity": "2",
    "pin": "123455666,122333333",
    "serial": "856073001_3,348311767_4",
    "cardName": "Eko Data Card Services",
    "type": "DATA_PRINT",
    "idempotencyKey": "681227cc-2638-49fe-bbe3-d2500cf54767"
  }
}

Best Practices & Next Steps

PIN & Serial Number Handling: Data card PINs and serial numbers are returned as comma-separated lists matching the requested quantity. Ensure your application parses and stores these securely, as PIN payloads are non-recoverable.

Safe Retries with Idempotency: Always attach a unique idempotencyKey (UUID v4) to your request body. If your connection drops or times out, you can safely resubmit the exact same request without risk of debiting your wallet twice.

Handling Pending Statuses: While most purchases complete in under 3 seconds, vendor delays can occasionally leave a transaction in a PENDING state. Do not retry with a new idempotency key. Instead, listen for real-time status updates via Webhooks.