Tv / Cable
Pay for DSTV, GOTV, and Startimes subscriptions.
Endpoints
Fetch Plans
GET /api/services/tv/plans
Verify IUC
POST /api/services/verify/tv
Purchase Subscription
POST /api/services/tv
All API requests must be made over HTTPS to: https://kda-turbo-web.vercel.app
Supported Providers
KDA currently supports subscription payments for all three major cable TV providers in Nigeria.
DSTV
Provider ID: kds-tv-dstv
GOTV
Provider ID: kds-tv-gotv
Startimes
Provider ID: kds-tv-startimes
Supported Plan Types
Across these providers, we support a wide variety of subscription packages. You can filter for specific classes using the type query parameter when fetching plans:
- DStv: Padi, Yanga, Compact, Premium, Confam, HDPVR, Addon, ExtraView, French
- GOTV: Max, Jollie, Jinja, Smallie, Supa
- Startimes: Dish, Antenna, Chinese
Fetch Plans
curl -X GET https://kda-turbo-web.vercel.app/api/services/tv/plans \
-H "Authorization: Bearer kds_test_YOUR_API_KEY"{
"success": true,
"count": 94,
"data": [
{
"type": "Padi",
"plans": [
{
"id": "kds-tv-dstv-padi-v1-001",
"label": "DStv Padi",
"validity": "1 Month",
"salePrice": "4400",
"provider": "DSTV"
}
]
},
{
"type": "Compact",
"plans": [...]
}
]
}Fetching without any filter returns all plans. Pass ?id=<planId> to fetch a single plan, or ?type=<category> to filter by category.
Fetch a single plan directly by its id:
curl -X GET "https://kda-turbo-web.vercel.app/api/services/tv/plans?id=kds-tv-dstv-padi-v1-001" \
-H "Authorization: Bearer kds_test_YOUR_API_KEY"You can also filter plans by category using the type query parameter:
curl -X GET "https://kda-turbo-web.vercel.app/api/services/tv/plans?type=Padi" \
-H "Authorization: Bearer kds_test_YOUR_API_KEY"Anatomy of a TV Plan
When you fetch plans, the response groups them by subscription type. Each group contains a plans array with individual plan objects:
{
"type": "Compact",
"plans": [
{
"id": "kds-tv-dstv-compact-v1-001",
"label": "DStv Compact",
"validity": "1 Month",
"salePrice": "19000",
"provider": "DSTV"
}
]
}Each plan object within a group:
Prop
Type
Purchase Flow
Verify IUC
Before purchasing, you can validate a smart card or IUC number against its provider to confirm it is active and retrieve the subscriber name.
Request Body
Prop
Type
Example
curl -X POST https://kda-turbo-web.vercel.app/api/services/verify/tv \
-H "Authorization: Bearer kds_test_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"slug": "kds-tv-gotv",
"smartCardNumber": "2021234567"
}'const response = await fetch("https://kda-turbo-web.vercel.app/api/services/verify/tv", {
method: "POST",
headers: {
"Authorization": "Bearer kds_test_YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
slug: "kds-tv-startimes",
smartCardNumber: "2021234567",
})
});
const data = await response.json();import requests
response = requests.post(
"https://kda-turbo-web.vercel.app/api/services/verify/tv",
headers={
"Authorization": "Bearer kds_test_YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"slug": "kds-tv-dstv",
"smartCardNumber": "2021234567",
},
)
data = response.json()<?php
$ch = curl_init("https://kda-turbo-web.vercel.app/api/services/verify/tv");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer kds_test_YOUR_API_KEY",
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"slug" => "kds-tv-gotv",
"smartCardNumber" => "2021234567",
]),
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
print_r($data);Success Response
{
"success": true,
"data": {
"valid": true,
"name": "Sadiq Musa"
}
}Error Response
{
"success": false,
"message": "INVALID IUC/SMARTCARD"
}Purchase Request
Request Body
Prop
Type
Example
curl -X POST https://kda-turbo-web.vercel.app/api/services/tv \
-H "Authorization: Bearer kds_test_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"planId": "kds-tv-gotv-v1-001",
"iucNumber": "2021234567",
"idempotencyKey": "681227cc-2638-49fe-bbe3-d2500cf54767"
}'const response = await fetch("https://kda-turbo-web.vercel.app/api/services/tv", {
method: "POST",
headers: {
"Authorization": "Bearer kds_test_YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
planId: "kds-tv-gotv-v1-001",
iucNumber: "2021234567",
idempotencyKey: crypto.randomUUID()
})
});
const data = await response.json();import requests
import uuid
response = requests.post(
"https://kda-turbo-web.vercel.app/api/services/tv",
headers={
"Authorization": "Bearer kds_test_YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"planId": "kds-tv-gotv-v1-001",
"iucNumber": "2021234567",
"idempotencyKey": str(uuid.uuid4()),
},
)
data = response.json()<?php
$ch = curl_init("https://kda-turbo-web.vercel.app/api/services/tv");
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-tv-gotv-v1-001",
"iucNumber" => "2021234567",
"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
{
"success": true,
"message": "Tv Subscription purchase successful!",
"transactionId": "KDS-TV-1HHOJ1TT-SN",
"data": {
"amount": 4400,
"label": "DStv Padi",
"planId": "kds-tv-dstv-padi-v1-001",
"provider": "DSTV",
"iucNumber": "1234567890",
"status": "SUCCESS",
"description": "Tv Subscription purchase successful!",
"transactionId": "KDS-TV-1HHOJ1TT-SN",
"createdAt": "2026-06-17T11:46:36.118Z",
"validity": "1 Month",
"category": "Padi",
"type": "TV",
"idempotencyKey": "1ab32145-036d-4fd2-b5b2-f5eda741bf93"
}
}Best Practices & Next Steps
Smartcard Verification: Always verify the decoder / IUC number using the Verify Smartcard endpoint prior to purchase. This ensures the account owner name matches before debiting funds.
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.