# BVN Retrieval
Source: https://docs.vtulab.com/docs/api-reference/identity/bvn-retrieve
post /identity/bvn/retrieve
Retrieve BVN details using a phone number.
Retrieve BVN details associated with a phone number.
```bash cURL theme={null}
curl --request POST \
--url https://api.vtulab.com/v1/identity/bvn/retrieve \
--header 'Authorization: Bearer YOUR_API_KEY' \
--data '{
"phone_number": "08123456789",
"is_consent": true
}'
```
# BVN Verification
Source: https://docs.vtulab.com/docs/api-reference/identity/bvn-verify
post /identity/bvn/verify
Verify Bank Verification Numbers instantly.
The BVN Verification API allows you to validate the bank records of individuals. This is a critical step for KYC (Know Your Customer) in fintech applications.
### Modes
* **Basic**: Essential profile data.
* **Advanced**: Full profile data including residential address and more.
Identity services can be tested using the Sandbox environment with your `test_...` key. Test requests will return mock data and won't charge your wallet.
```bash cURL theme={null}
curl --request POST \
--url https://api.vtulab.com/v1/identity/bvn/verify \
--header 'Authorization: Bearer YOUR_API_KEY' \
--data '{
"bvn": "12345678901",
"is_consent": true,
"mode": "basic"
}'
```
# NIN Retrieval
Source: https://docs.vtulab.com/docs/api-reference/identity/nin-retrieve
post /identity/nin/retrieve
Find NIN details using a linked phone number.
Retrieve NIN details associated with a specific phone number. This is useful when the individual has lost their NIN but has access to their registered phone number.
### Usage Requirements
1. **Phone Number**: Must be the 11-digit number registered with the NIN.
2. **Consent**: You must confirm that you have obtained consent from the user.
Retrieval services carry a higher charge than simple verification. Check your current rates in the dashboard.
```bash cURL theme={null}
curl --request POST \
--url https://api.vtulab.com/v1/identity/nin/retrieve \
--header 'Authorization: Bearer YOUR_API_KEY' \
--data '{
"phone_number": "08123456789",
"is_consent": true
}'
```
# NIN Verification
Source: https://docs.vtulab.com/docs/api-reference/identity/nin-verify
POST /identity/nin/verify
Securely verify National Identification Numbers in real-time.
Verify the identity of individuals using their National Identification Number (NIN). Our API provides access to verified records from the NIMC database.
**Consent Required**: You must obtain explicit consent from the individual before verifying their NIN. Requests without `is_consent: true` will be rejected.
### Verification Modes
We offer two modes of verification to suit your needs:
* **Basic**: Returns essential information (Full Name, Gender, Date of Birth).
* **Advanced**: Returns comprehensive details including the individual's photo (Base64).
```bash cURL theme={null}
curl --request POST \
--url https://api.vtulab.com/v1/identity/nin/verify \
--header 'Authorization: Bearer YOUR_API_KEY' \
--data '{
"nin": "12345678901",
"is_consent": true,
"mode": "basic"
}'
```
```json Success (Basic) theme={null}
{
"status": true,
"message": "NIN Verified Successfully",
"data": {
"transaction": {
"title": "NIN Verification",
"amount": 100,
"reference": "VERIFY_65E8F...",
"status": "success"
},
"result": {
"first_name": "JOHN",
"last_name": "DOE",
"middle_name": "JAMES",
"gender": "M",
"date_of_birth": "1990-01-01"
}
}
}
```
# Purchase Airtime
Source: https://docs.vtulab.com/docs/api-reference/vtu/airtime-purchase
post /vtu/airtime/purchase
Top up any mobile number with airtime instantly.
Send airtime to any mobile network in Nigeria. The transaction is processed in real-time.
### Important Notes
* Minimum amount is **NGN 50**.
* The `network` parameter is case-insensitive.
* Always use the 11-digit format for phone numbers (e.g., `08123456789`).
```bash cURL theme={null}
curl --request POST \
--url https://api.vtulab.com/v1/vtu/airtime/purchase \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"network": "mtn",
"phone_number": "08123456789",
"amount": 100
}'
```
# Data Catalog
Source: https://docs.vtulab.com/docs/api-reference/vtu/data-catalog
get /vtu/data
Retrieve available mobile networks and data plans.
This endpoint returns a comprehensive list of all active mobile networks and their associated data plans. We recommend caching this response for at least 1 hour to optimize performance.
### Use Case
* Displaying a list of networks to the user.
* Populating a dropdown of data plans.
* Syncing plan IDs and pricing with your local database.
The `price` field in the response is the amount that will be debited from your VTULab wallet for the specific plan.
```bash cURL theme={null}
curl --request GET \
--url https://api.vtulab.com/v1/vtu/data \
--header 'Authorization: Bearer YOUR_API_KEY'
```
```json Success theme={null}
{
"status": true,
"message": "Data catalog fetched successfully",
"data": {
"networks": [
{
"id": 1,
"name": "MTN",
"code": "mtn"
}
],
"data_plans": [
{
"id": 101,
"network_id": 1,
"name": "500MB SME",
"price": 150,
"validity": "30 Days"
}
]
}
}
```
# Purchase Data
Source: https://docs.vtulab.com/docs/api-reference/vtu/data-purchase
POST /vtu/data/purchase
Buy a data bundle for a specific phone number.
Purchase a data bundle instantly for any Nigerian mobile number. Ensure your wallet has sufficient balance before making a request in live mode.
### Request Body
The request requires the `network_id`, `plan_id` (obtained from the catalog), and the recipient's `phone_number`.
```bash cURL theme={null}
curl --request POST \
--url https://api.vtulab.com/v1/vtu/data/purchase \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"network_id": 1,
"plan_id": 101,
"phone_number": "08123456789",
"reference": "unique_ref_123"
}'
```
```json Success theme={null}
{
"status": true,
"message": "Data purchase successful",
"data": {
"transaction": {
"reference": "DATA_65E8F...",
"status": "success",
"amount": 150,
"description": "MTN 1GB SME Data to 08123456789"
}
}
}
```
# Authentication
Source: https://docs.vtulab.com/docs/authentication
Securely access the VTULab API using API keys.
VTULab uses API keys to authorize requests. All API requests must be made over [HTTPS](https://en.wikipedia.org/wiki/HTTPS) and include an API key.
## API Keys
You can find your API keys in the [API Settings](https://vtulab.com/user/settings/api) of your dashboard. We provide two keys for different environments:
Used for real transactions. Ensure your wallet is funded before using this key.
Used for sandbox testing. Transactions made with this key are simulated and do not debit your balance.
## Authentication Format
We support two ways to provide your API key in the request headers:
### 1. Bearer Token (Recommended)
Include your key in the `Authorization` header.
```http theme={null}
Authorization: Bearer YOUR_API_KEY
```
### 2. Custom Header
Alternatively, you can use the `X-API-KEY` header.
```http theme={null}
X-API-KEY: YOUR_API_KEY
```
***
## IP Whitelisting
For maximum security, you must whitelist the IP addresses of your servers. Requests originating from non-whitelisted IPs will be rejected with a `403 Forbidden` error.
You can manage your whitelisted IPs in the **API Settings** section of the dashboard.
## Base URL
All API requests should be prefixed with the following base URL:
```bash theme={null}
https://api.vtulab.com/v1
```
## API Status Codes
| Code | Description |
| :---- | :----------------------------------------------------------- |
| `200` | **Success**: The request was successful. |
| `401` | **Unauthorized**: Invalid or missing API key. |
| `403` | **Forbidden**: IP not whitelisted or account restricted. |
| `422` | **Unprocessable Entity**: Validation errors in your payload. |
| `429` | **Too Many Requests**: Rate limit exceeded. |
```bash cURL theme={null}
curl -X GET "https://api.vtulab.com/v1/vtu/data" \
-H "Authorization: Bearer YOUR_API_KEY"
```
```javascript Node.js theme={null}
const axios = require('axios');
axios.get('https://api.vtulab.com/v1/vtu/data', {
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
});
```
# Base URL
Source: https://docs.vtulab.com/docs/base-url
The root endpoint for all VTULab API requests.
All API requests to VTULab should be made using the base URL below. Our API is versioned to ensure stability as we introduce new features.
## Production Environment
The production base URL for all endpoints is:
`https://api.vtulab.com/v1`
## HTTPS Only
To protect your data and API keys, the VTULab API requires all requests to be made over **HTTPS**. Unencrypted HTTP requests will be automatically rejected.
## Versioning
The current version of the API is `v1`. We include the version number in the URL path to maintain backward compatibility for existing integrations.
***
When testing your integration, you can use the same base URL with your **Test Key**. The system will automatically process the request in Sandbox mode.
# Errors
Source: https://docs.vtulab.com/docs/errors
Understanding and handling API error responses.
VTULab uses standard HTTP response codes to indicate the success or failure of an API request. In general, codes in the `2xx` range indicate success, codes in the `4xx` range indicate an error that failed given the information provided (e.g., a required parameter was omitted, a charge failed, etc.), and codes in the `5xx` range indicate an error with VTULab's servers.
## HTTP Status Codes
| Code | Description |
| :----------------------------------- | :----------------------------------------------------------------------------- |
| `200 - OK` | Everything worked as expected. |
| `400 - Bad Request` | The request was unacceptable, often due to missing a required parameter. |
| `401 - Unauthorized` | No valid API key provided. |
| `403 - Forbidden` | The API key doesn't have permissions for the request or IP is not whitelisted. |
| `404 - Not Found` | The requested resource doesn't exist. |
| `422 - Unprocessable Entity` | Validation errors (e.g. invalid phone number format). |
| `429 - Too Many Requests` | Too many requests hit the API too quickly. |
| `500, 502, 503, 504 - Server Errors` | Something went wrong on VTULab's end. |
## Error Response Structure
When a request fails, we return a JSON object containing the error details.
```json Error Example theme={null}
{
"status": false,
"message": "The given data was invalid.",
"errors": {
"phone_number": [
"The phone number must be exactly 11 digits."
]
}
}
```
### Field Definitions
Always `false` for error responses.
A high-level summary of the error.
An object containing field-specific validation messages. The keys represent the field names, and the values are arrays of error strings.
***
## Handling Errors
### Validation Errors (422)
These occur when the data you sent doesn't meet our requirements. Always check the `errors` object for specific details.
### Authentication Errors (401/403)
Double-check that your API key is correctly formatted in the header and that your server's IP address is whitelisted in the dashboard.
### Rate Limiting (429)
If you hit our rate limits, slow down your requests and implement a retry logic with exponential backoff.
Need help? Contact our support team at [support@vtulab.com](mailto:support@vtulab.com) with your transaction reference or request payload.
# Going Live
Source: https://docs.vtulab.com/docs/going-live
Transitioning your integration from Test to Production.
Once you have completed your integration and testing using the **Test Key**, follow these steps to start processing real transactions.
## Checklist for Production
Before switching to your Live Key, ensure you have completed the following:
Ensure your production server's IP address is whitelisted in the [API Settings](https://vtulab.com/user/settings/api).
Replace your `test_...` key with your `live_...` key in your environment variables.
Identity and VTU services are charged in real-time. Ensure your wallet has sufficient balance for live operations.
Make sure your live webhook URL is configured and your server is ready to receive `transaction.updated` events.
## Live vs. Test Mode
| Feature | Test Mode (Sandbox) | Live Mode (Production) |
| :------------------- | :------------------------ | :------------------------------ |
| **API Key** | `test_...` | `live_...` |
| **Wallet Impact** | None (Simulated) | Real-time debit |
| **Service Delivery** | Simulated success/failure | Real delivery to telcos/NIMC |
| **Reference Prefix** | `TEST_...` | `DATA_...`, `AIRTIME_...`, etc. |
**Important**: Double-check your recipient phone numbers in Live mode. Transactions made to wrong numbers cannot be reversed once successful.
We recommend performing a small transaction (e.g., 100 Airtime) with your Live Key to verify the end-to-end flow before opening your application to all users.
# Introduction
Source: https://docs.vtulab.com/docs/introduction
Build and scale your fintech products with VTULab APIs.
# Build airtime, data, and identity products with VTULab
Integrate airtime, data bundles, and identity services into your applications with a single, unified API designed for developers.
Get your API keys and make your first request in under 5 minutes.
Explore our interactive API explorer and try endpoints in real-time.
## Core Services
Everything you need to power your mobile services and identity workflows.
Automated top-up for MTN, Airtel, Glo, and 9mobile.
SME, Gifting, and Corporate Gifting bundles across all networks.
Real-time identity verification via NIMC database.
Validate bank records and KYC details instantly.
Automated wallet funding for seamless transactions.
Query and track every transaction with detailed status reports.
## Seamless Integration
Get started with just a few lines of code. No complex setups or legacy protocols.
```bash cURL theme={null}
curl --request GET \
--url https://api.vtulab.com/v1/vtu/data \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Accept: application/json'
```
```javascript Node.js theme={null}
const axios = require('axios');
const response = await axios.get('https://api.vtulab.com/v1/vtu/data', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
});
console.log(response.data);
```
## Why developers choose VTULab
Modern REST APIs, detailed documentation, and a native sandbox environment.
99.9% uptime with redundant connections to all major providers.
Built to handle high-volume traffic with low-latency response times.
Receive real-time notifications for transaction updates and wallet events.
## Quick Start
Follow these four steps to go from zero to production.
Sign up at [vtulab.com](https://vtulab.com/register) to access your developer dashboard.
Obtain your **Test** and **Live** keys from the **Settings > API** section.
Use your Test Key to call the [Data Catalog](/docs/api-reference/vtu/data-catalog) endpoint.
Fund your wallet, switch to your Live Key, and start processing real transactions.
**Need help?** Our developer support team is available 24/7. Join our [Discord Community](https://discord.gg/vtulab) or email [support@vtulab.com](mailto:support@vtulab.com).
# Making your First Request
Source: https://docs.vtulab.com/docs/making-first-request
A step-by-step guide to sending your first authenticated request.
In this guide, we will use `curl` to fetch the data catalog. This is the best way to verify that your API key and IP whitelisting are configured correctly.
## 1. Prepare your API Key
Copy your **Test Key** from the VTULab Dashboard. It should look like `test_...`.
## 2. Construct the Request
We will call the `GET /v1/vtu/data` endpoint. This endpoint does not require any parameters and is used to retrieve available data plans.
```bash theme={null}
curl --request GET \
--url https://api.vtulab.com/v1/vtu/data \
--header 'Authorization: Bearer YOUR_TEST_KEY' \
--header 'Accept: application/json'
```
## 3. Analyze the Response
A successful response will return a `200 OK` status and a JSON body containing `networks` and `data_plans`.
```json theme={null}
{
"status": true,
"message": "Data catalog fetched successfully",
"data": {
"networks": [...],
"data_plans": [...]
}
}
```
## Common Issues
If your request fails, check the following:
Ensure you are passing the key correctly in the `Authorization` header as a Bearer token.
Verify that the IP address of the machine making the request is added to your whitelist in the VTULab Dashboard.
You have exceeded the rate limit. Wait a few seconds and try again.
Once you've successfully fetched the catalog, you're ready to start [Purchasing Data](/docs/vtu/data#purchase-data).
# Quickstart
Source: https://docs.vtulab.com/docs/quick-start
Get up and running with VTULab in less than 5 minutes.
Welcome to the VTULab Quickstart guide. This guide will walk you through the essential steps to start using our APIs for VTU and identity services.
### Prerequisites
Before you begin, ensure you have:
* A [VTULab Account](https://vtulab.com/register).
* Basic knowledge of making HTTP requests.
***
Log in to your [VTULab Dashboard](https://vtulab.com/user/dashboard) and navigate to **Settings > API**. Here you will find your **Test Key** and **Live Key**. Use the Test Key for initial development.
For security, VTULab requires you to whitelist the IP address of the server making the API requests. Add your IP in the **API Settings** section.
Identity and live VTU services require a funded wallet. You can fund your wallet via bank transfer or card payment in the dashboard.
Try the [Get Data Catalog](/docs/vtu/data) endpoint using your Test Key to see available plans.
## Next Steps
Now that you're set up, you can:
Detailed walkthrough of sending your first API call.
Explore the full API documentation and try it out in the playground.
Need help during integration? Reach out to our developer support team at [support@vtulab.com](mailto:support@vtulab.com).
# Rate Limits
Source: https://docs.vtulab.com/docs/rate-limits
Understanding the API usage limits on VTULab.
To ensure the stability and reliability of our platform for all users, VTULab implements rate limits on all API requests.
## Standard Limits
Rate limits are applied based on your API key and are calculated on a per-minute basis.
| Service Type | Rate Limit |
| :------------------------------- | :---------------------- |
| **VTU Services** (Data, Airtime) | 60 requests per minute |
| **Identity Services** (NIN, BVN) | 30 requests per minute |
| **Information/Catalog** (GET) | 120 requests per minute |
## Handling Rate Limits
When you exceed a rate limit, the API will return a `429 Too Many Requests` error.
### Headers
Our API includes headers in every response to help you track your current usage:
* `X-RateLimit-Limit`: The maximum number of requests allowed in the period.
* `X-RateLimit-Remaining`: The number of requests remaining in the current period.
* `Retry-After`: The number of seconds to wait before making another request.
### Best Practices
Use exponential backoff in your retry logic when you receive a 429 error.
Do not call the Data Catalog endpoint for every transaction. Cache it for at least 1 hour.
Need higher limits for a high-volume application? Contact our sales team at [sales@vtulab.com](mailto:sales@vtulab.com) to discuss custom plans.
# Webhooks
Source: https://docs.vtulab.com/docs/webhooks
Real-time event notifications for your transactions.
Webhooks enable your application to receive real-time notifications from VTULab. Instead of polling our API to check if a transaction is complete, we'll push the status update directly to your server as soon as it happens.
Configure your endpoint URL in the **API Settings** section of your dashboard.
## Supported Events
Currently, we support the following event:
| Event | Description |
| :-------------------- | :-------------------------------------------------------------------------------------------- |
| `transaction.updated` | Fired when a transaction's status changes (e.g., from `processing` to `success` or `failed`). |
## Payload Structure
When an event occurs, VTULab sends a `POST` request with a JSON body.
```json Payload Example theme={null}
{
"event": "transaction.updated",
"data": {
"reference": "DATA_65E8F0B2...",
"status": "success",
"amount": 150,
"type": "data",
"network": "MTN",
"phone_number": "08123456789",
"created_at": "2024-03-06T12:00:00Z"
}
}
```
### Field Definitions
The type of event being sent.
The unique VTULab transaction reference.
The new status: `success` or `failed`.
The transaction amount in NGN.
***
## Best Practices
### 1. Verification
Always verify that the webhook is originating from VTULab. We recommend checking the request's source IP against our official list or verifying the signature if provided.
### 2. Acknowledge Promptly
Your server should return a `200 OK` response within 5 seconds. If your processing logic takes longer, we recommend queuing the job and returning the response immediately.
### 3. Handle Idempotency
Ensure your webhook handler is idempotent. You might receive the same notification more than once in rare network scenarios. Use the `reference` field to track processed events.
## Example Handler (Node.js)
```javascript theme={null}
const express = require('express');
const app = express();
app.use(express.json());
app.post('/webhooks/vtulab', (req, res) => {
const { event, data } = req.body;
if (event === 'transaction.updated') {
console.log(`Transaction ${data.reference} updated to ${data.status}`);
// Perform your business logic here (e.g., credit user, send email)
}
// Always return a 200 OK
res.status(200).send('Webhook Received');
});
app.listen(3000, () => console.log('Webhook server running on port 3000'));
```