Utilities Unified API
One lookup-and-vend flow for utility and digital-service purchases: Cable TV, Electricity, Education, Internet and Betting.
Environment base URL:
Test: https://sandbox-api-d.squadco.com/v1/service
Production: https://api-d.squadco.com/v1/service
Authorization keys are to be passed via Headers as a Bearer token.
Example: Authorization: Bearer sandbox_sk_94f2b798466408ef4d19e848ee1a4d1a3e93f104046f
All requests must include the following headers:
Authorization: Bearer YOUR_SECRET_KEY
Content-Type: application/json
All request amount values are in naira. Product and transaction kobo_amount values are in kobo (₦5,000 = 500000).
Supported Utilities
| Service | What it supports | Provider codes |
|---|---|---|
CABLE | TV subscriptions and bouquet purchases | DSTV, GOTV, STARTIMES |
ELECTRICITY | Prepaid and postpaid electricity purchases | IE, AEDC, YEDC, BEDC, EKEDC, IBEDC, KEDCO, KAEDC, PHED, EEDC, APLE, JED |
EDUCATION | Education products and examination services | WAEC, JAMB |
INTERNET | Internet and broadband purchases | SMILE, SPECTRANET, IPNX, SWIFT, FOB (FiberOne Broadband) |
BETTING | Betting wallet funding | BETKING |
/billers is the authoritative discovery endpoint for supported codes. Product catalogues and configured service routes can change, so always send the code values returned by /billers and /products.
Endpoints
| Operation | Method | Path | Applies to |
|---|---|---|---|
| List billers | GET | /billers | All services |
| List products | POST | /products | Cable, Education, Internet |
| Validate customer | POST | /lookup | All services |
| Complete purchase | POST | /vend | All services |
| Check transaction | GET | /transactions/{merchant_reference} | All services |
Standard Flow
- Optionally retrieve
/billersand, where available,/products. - Call
/lookupto validate the customer. Save itsvalidation_token. - Call
/vendwith that token, a newmerchant_reference, contact details and the service-specific purchase input. - If vend returns HTTP
202/PENDING, query/transactions/{merchant_reference}. Do not vend again.
Response Codes
| HTTP status | Meaning |
|---|---|
200 | Success. The request completed. |
202 | Pending. The purchase is in progress; check its status with /transactions/{merchant_reference}. |
400 | Bad request. A field is missing or invalid. Check the message and fix the request. |
403 | Unauthorized. The Authorization header is missing or the key is invalid for this environment. |
List Billers
This endpoint returns the supported services and provider codes for your deployment. Filter by a single service with the service query parameter.
This API retrieves the list of supported billers
Parameters
Query
service*
String
Optional. Filter billers by service: CABLE, ELECTRICITY, EDUCATION, INTERNET or BETTING
Sample Request
GET /billers
To return a single service, add the service query parameter, for example GET /billers?service=INTERNET.
Sample Response
- 200: Success
- 400: Bad Request
- 403: Unauthorized
{
"status": 200,
"success": true,
"message": "Billers retrieved successfully",
"data": {
"billers": [
{
"code": "CABLE",
"name": "Cable TV",
"providers": [
{
"code": "GOTV",
"name": "GOtv",
"total_rate_percent": null,
"total_rate_cap": null,
"type": "cable"
},
{
"code": "DSTV",
"name": "DStv",
"total_rate_percent": null,
"total_rate_cap": null,
"type": "cable"
},
{
"code": "STARTIMES",
"name": "StarTimes",
"total_rate_percent": null,
"total_rate_cap": null,
"type": "cable"
}
]
},
{
"code": "ELECTRICITY",
"name": "Electricity",
"providers": [
{
"code": "IE",
"name": "Ikeja Electric",
"total_rate_percent": null,
"total_rate_cap": null,
"type": "electricity"
},
{
"code": "AEDC",
"name": "Abuja Electricity",
"total_rate_percent": null,
"total_rate_cap": null,
"type": "electricity"
},
{
"code": "YEDC",
"name": "Yola Electricity",
"total_rate_percent": null,
"total_rate_cap": null,
"type": "electricity"
},
{
"code": "BEDC",
"name": "Benin Electricity",
"total_rate_percent": null,
"total_rate_cap": null,
"type": "electricity"
},
{
"code": "EKEDC",
"name": "Eko Electricity",
"total_rate_percent": null,
"total_rate_cap": null,
"type": "electricity"
},
{
"code": "IBEDC",
"name": "Ibadan Electricity",
"total_rate_percent": null,
"total_rate_cap": null,
"type": "electricity"
},
{
"code": "KEDCO",
"name": "Kano Electricity",
"total_rate_percent": null,
"total_rate_cap": null,
"type": "electricity"
},
{
"code": "KAEDC",
"name": "Kaduna Electricity",
"total_rate_percent": null,
"total_rate_cap": null,
"type": "electricity"
},
{
"code": "PHED",
"name": "Port Harcourt Electricity",
"total_rate_percent": null,
"total_rate_cap": null,
"type": "electricity"
},
{
"code": "EEDC",
"name": "Enugu Electricity",
"total_rate_percent": null,
"total_rate_cap": null,
"type": "electricity"
},
{
"code": "APLE",
"name": "Aba Power",
"total_rate_percent": null,
"total_rate_cap": null,
"type": "electricity"
},
{
"code": "JED",
"name": "Jos Electricity",
"total_rate_percent": null,
"total_rate_cap": null,
"type": "electricity"
}
]
},
{
"code": "EDUCATION",
"name": "Education",
"providers": [
{
"code": "WAEC",
"name": "WAEC",
"total_rate_percent": null,
"total_rate_cap": null,
"type": "education"
},
{
"code": "JAMB",
"name": "JAMB",
"total_rate_percent": null,
"total_rate_cap": null,
"type": "education"
}
]
},
{
"code": "INTERNET",
"name": "Internet",
"providers": [
{
"code": "SMILE",
"name": "Smile",
"total_rate_percent": null,
"total_rate_cap": null,
"type": "internet"
},
{
"code": "SPECTRANET",
"name": "Spectranet",
"total_rate_percent": null,
"total_rate_cap": null,
"type": "internet"
},
{
"code": "IPNX",
"name": "ipNX",
"total_rate_percent": null,
"total_rate_cap": null,
"type": "internet"
},
{
"code": "SWIFT",
"name": "Swift",
"total_rate_percent": null,
"total_rate_cap": null,
"type": "internet"
},
{
"code": "FOB",
"name": "FiberOne Broadband",
"total_rate_percent": null,
"total_rate_cap": null,
"type": "internet"
}
]
},
{
"code": "BETTING",
"name": "Betting",
"providers": [
{
"code": "BETKING",
"name": "BetKing",
"total_rate_percent": null,
"total_rate_cap": null,
"type": "betting"
}
]
}
]
}
}
{
"status": 400,
"success": false,
"message": "ERROR_MESSAGE",
"data": {}
}
{
"status": 403,
"success": false,
"message": "ERROR_MESSAGE",
"data": {}
}
List Products
Product catalogues are available for Cable, Education and Internet. Always use the returned product code and price rather than hard-coding either.
This API retrieves the product catalogue for a provider
Parameters
Body
service*
String
Service code returned by /billers. One of CABLE, EDUCATION or INTERNET
provider*
String
Provider code returned by /billers, e.g. DSTV, WAEC, SMILE
Sample Request
{
"service": "INTERNET",
"provider": "SMILE"
}
- 200: Success
- 400: Bad Request
- 403: Unauthorized
{
"status": 200,
"success": true,
"data": {
"service": "INTERNET",
"provider": "SMILE",
"products": [
{
"code": "PRODUCT_CODE",
"name": "Product name",
"kobo_amount": 500000,
"currency": "NGN"
}
]
}
}
{
"status": 400,
"success": false,
"message": "ERROR_MESSAGE",
"data": {}
}
{
"status": 403,
"success": false,
"message": "ERROR_MESSAGE",
"data": {}
}
Lookup
Every purchase begins with a lookup. A successful response contains a validation_token, which is required for the related vend request.
This API validates a customer before a purchase
Parameters
Body
service*
String
Service code: CABLE, ELECTRICITY, EDUCATION, INTERNET or BETTING
provider*
String
Provider code returned by /billers
customer_identifier*
String
Smart-card/decoder number, meter/account number, candidate ID, internet account/phone identifier or betting account ID, depending on the service
context*
Object
Service-specific context. ELECTRICITY: { meter_type: prepaid | postpaid }. EDUCATION: { product_code } plus any product-required fields. INTERNET: optional { product_code }. Not required for CABLE or BETTING
Lookup input per service
| Service | customer_identifier | Required context |
|---|---|---|
CABLE | Smart-card or decoder number | None |
ELECTRICITY | Meter or electricity account number | { "meter_type": "prepaid" } or { "meter_type": "postpaid" } |
EDUCATION | Candidate/customer identifier required by the product | { "product_code": "..." }, plus any product-required fields |
INTERNET | Customer account/phone identifier | Optional { "product_code": "..." } |
BETTING | Betting account ID | None |
Sample Request
- Cable
- Electricity
- Education
- Internet
- Betting
{
"service": "CABLE",
"provider": "DSTV",
"customer_identifier": "SMART_CARD_NUMBER"
}
{
"service": "ELECTRICITY",
"provider": "IE",
"customer_identifier": "METER_NUMBER",
"context": {
"meter_type": "prepaid"
}
}
{
"service": "EDUCATION",
"provider": "WAEC",
"customer_identifier": "CANDIDATE_ID",
"context": {
"product_code": "PRODUCT_CODE"
}
}
{
"service": "INTERNET",
"provider": "SMILE",
"customer_identifier": "ACCOUNT_OR_PHONE",
"context": {
"product_code": "PRODUCT_CODE"
}
}
{
"service": "BETTING",
"provider": "BETKING",
"customer_identifier": "BETTING_ACCOUNT_ID"
}
Sample Response
- 200: Success
- 400: Bad Request
- 403: Unauthorized
{
"status": 200,
"success": true,
"data": {
"validation_token": "LOOKUP_TOKEN",
"service": "EDUCATION",
"provider": "WAEC",
"customer_name": "Customer name"
}
}
{
"status": 400,
"success": false,
"message": "ERROR_MESSAGE",
"data": {}
}
{
"status": 403,
"success": false,
"message": "ERROR_MESSAGE",
"data": {}
}
Electricity, Internet and Betting lookups may also return minimum_vend; Betting may return maximum_vend. Electricity also returns available account and meter information. Validate the amount against these limits before calling /vend.
Vend
Every vend request needs the lookup validation_token, a unique merchant_reference and customer contact details, plus the service-specific purchase input.
This API completes a purchase
Parameters
Body
validation_token*
String
The validation_token returned by /lookup. Single-use
merchant_reference*
String
A new, unique reference you generate for this purchase
customer.phone_number*
String
Customer phone number
customer.email*
String
Customer email address
amount*
Number
Amount in naira. Required for ELECTRICITY, BETTING and variable-price EDUCATION/INTERNET purchases. Do not send together with products
products*
Array
Product objects ({ code, quantity, amount }). CABLE: 1-10 items, quantity defaults to 1. EDUCATION/INTERNET: one item when product selection was deferred at lookup. Do not send together with amount
Purchase input per service
| Service | Vend input |
|---|---|
CABLE | products: 1–10 product objects, each with a returned code; quantity defaults to 1. |
ELECTRICITY | Top-level amount in naira, meeting the lookup minimum. |
BETTING | Top-level amount in naira, within lookup limits. |
EDUCATION | A fixed-price lookup needs no amount. A variable-price lookup uses top-level amount, or one products item with its amount when product selection is deferred. |
INTERNET | A selected fixed-price product needs no amount. A selected variable-price product uses top-level amount; when selection is deferred, send one products item, with its amount for variable-price products. |
Do not send both top-level amount and products. A product submitted at vend must match the product selected at lookup, if one was selected.
Sample Request
- Cable
- Electricity / Betting / Variable-price
- Fixed-price product
- Deferred product selection
{
"validation_token": "LOOKUP_TOKEN",
"merchant_reference": "ORDER-20260914-00001",
"products": [
{ "code": "PRODUCT_CODE", "quantity": 1 }
],
"customer": {
"phone_number": "08012345678",
"email": "customer@example.com"
}
}
{
"validation_token": "LOOKUP_TOKEN",
"merchant_reference": "ORDER-20260914-00002",
"amount": 2000,
"customer": {
"phone_number": "08012345678",
"email": "customer@example.com"
}
}
{
"validation_token": "LOOKUP_TOKEN",
"merchant_reference": "ORDER-20260914-00003",
"customer": {
"phone_number": "08012345678",
"email": "customer@example.com"
}
}
{
"validation_token": "LOOKUP_TOKEN",
"merchant_reference": "ORDER-20260914-00004",
"products": [
{ "code": "PRODUCT_CODE", "amount": 2000 }
],
"customer": {
"phone_number": "08012345678",
"email": "customer@example.com"
}
}
Sample Response
Successful vend responses include processed_status: "SUCCESS", service/provider information and service-specific results, for example an electricity token and units, a Cable bouquet, an Education PIN where applicable, Internet purchase details, or Betting funding details.
- 200: Success
- 202: Pending
- 400: Bad Request
- 403: Unauthorized
{
"status": 200,
"success": true,
"message": "Success",
"data": {
"validation_token": "LOOKUP_TOKEN",
"merchant_reference": "ORDER-20260914-00001",
"service": "CABLE",
"provider": "DSTV",
"processed_status": "SUCCESS",
"response_code": "SUCCESS",
"bouquet": {
"code": "PRODUCT_CODE",
"name": "Product name",
"kobo_amount": 500000,
"currency": "NGN"
}
}
}
{
"status": 202,
"success": true,
"message": "PENDING_MESSAGE",
"data": {
"merchant_reference": "ORDER-20260914-00001",
"processed_status": "PENDING",
"next_retry_at": "NEXT_RETRY_TIMESTAMP"
}
}
{
"status": 400,
"success": false,
"message": "ERROR_MESSAGE",
"data": {}
}
{
"status": 403,
"success": false,
"message": "ERROR_MESSAGE",
"data": {}
}
Transaction Status
Use the merchant reference to retrieve the latest state of a purchase. A final successful transaction has processed_status: "SUCCESS". A 202 response with processed_status: "PENDING" means the external result is still being confirmed; keep the reference and retry the status endpoint at next_retry_at when supplied.
This API retrieves the status of a transaction
Parameters
Path
merchant_reference*
String
The merchant_reference sent with the vend request
Sample Request
GET /transactions/ORDER-20260914-00001
- 200: Success
- 202: Pending
- 400: Bad Request
- 403: Unauthorized
{
"status": 200,
"success": true,
"message": "Success",
"data": {
"transaction": {
"validation_token": "LOOKUP_TOKEN",
"merchant_reference": "ORDER-20260914-00001",
"service": "CABLE",
"provider": "DSTV",
"processed_status": "SUCCESS",
"response_code": "SUCCESS",
"customer_id": "41234567890",
"kobo_amount": 500000,
"currency": "NGN",
"product_code": "PRODUCT_CODE",
"created_at": "2026-09-14T12:00:00.000Z",
"details": {
"name": "Product name",
"code": "PRODUCT_CODE",
"kobo_amount": 500000,
"currency": "NGN"
}
}
}
}
{
"status": 202,
"success": true,
"message": "PENDING_MESSAGE",
"data": {
"transaction": {
"merchant_reference": "ORDER-20260914-00001",
"processed_status": "PENDING",
"next_retry_at": "NEXT_RETRY_TIMESTAMP"
}
}
}
{
"status": 400,
"success": false,
"message": "ERROR_MESSAGE",
"data": {}
}
{
"status": 403,
"success": false,
"message": "ERROR_MESSAGE",
"data": {}
}
Integration Rules
- Treat
validation_tokenas single-use and specific to its lookup. - Generate a new
merchant_referencefor every purchase; use it for status checks and safe retry handling. - Treat only
SUCCESSas final success. Do not resubmit a pending vend. - Use product codes returned by
/products; values and availability may change. - Do not expose or depend on vendor references or vendor-specific product codes.
A pending transaction is already in progress. Poll its status using merchant_reference; do not submit another vend for the same purchase.
GO LIVE - Production
To use this API in production:
- Change the base URL of the endpoint from https://sandbox-api-d.squadco.com/v1/service to https://api-d.squadco.com/v1/service
- Get production keys from your live account and replace the test authorization keys.