Top-Up eSIM
curl --request POST \
--url https://api.vellosim.com/api/esim/buy \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"packageCode": "<string>",
"paymentMethod": "<string>",
"packageType": "<string>",
"esimId": "<string>"
}
'const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
packageCode: '<string>',
paymentMethod: '<string>',
packageType: '<string>',
esimId: '<string>'
})
};
fetch('https://api.vellosim.com/api/esim/buy', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.vellosim.com/api/esim/buy"
payload = {
"packageCode": "<string>",
"paymentMethod": "<string>",
"packageType": "<string>",
"esimId": "<string>"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.vellosim.com/api/esim/buy",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'packageCode' => '<string>',
'paymentMethod' => '<string>',
'packageType' => '<string>',
'esimId' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.vellosim.com/api/esim/buy"
payload := strings.NewReader("{\n \"packageCode\": \"<string>\",\n \"paymentMethod\": \"<string>\",\n \"packageType\": \"<string>\",\n \"esimId\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"transactionId": "esim_1697888400_12345",
"status": "SUCCESS",
"message": "Top-up applied successfully",
"package": {
"packageCode": "CKH384_TOPUP_3GB",
"name": "USA Top-Up 3GB - 30 Days",
"price": 6.90,
"currencyCode": "USD",
"volume": 3221225472,
"duration": 30
},
"esimDetails": {
"iccid": "8901234567890123456",
"totalVolume": 8589934592,
"dataRemaining": 6442450944
}
}
{
"success": false,
"message": "Insufficient wallet balance",
"statusCode": 400
}
{
"success": false,
"message": "esimId is required for TOPUP package type",
"statusCode": 400
}
{
"success": false,
"message": "eSIM not found or does not belong to your account",
"statusCode": 404
}
Purchase
Top-Up eSIM
Add more data to an existing eSIM
POST
/
api
/
esim
/
buy
Top-Up eSIM
curl --request POST \
--url https://api.vellosim.com/api/esim/buy \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"packageCode": "<string>",
"paymentMethod": "<string>",
"packageType": "<string>",
"esimId": "<string>"
}
'const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
packageCode: '<string>',
paymentMethod: '<string>',
packageType: '<string>',
esimId: '<string>'
})
};
fetch('https://api.vellosim.com/api/esim/buy', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.vellosim.com/api/esim/buy"
payload = {
"packageCode": "<string>",
"paymentMethod": "<string>",
"packageType": "<string>",
"esimId": "<string>"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.vellosim.com/api/esim/buy",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'packageCode' => '<string>',
'paymentMethod' => '<string>',
'packageType' => '<string>',
'esimId' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.vellosim.com/api/esim/buy"
payload := strings.NewReader("{\n \"packageCode\": \"<string>\",\n \"paymentMethod\": \"<string>\",\n \"packageType\": \"<string>\",\n \"esimId\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"transactionId": "esim_1697888400_12345",
"status": "SUCCESS",
"message": "Top-up applied successfully",
"package": {
"packageCode": "CKH384_TOPUP_3GB",
"name": "USA Top-Up 3GB - 30 Days",
"price": 6.90,
"currencyCode": "USD",
"volume": 3221225472,
"duration": 30
},
"esimDetails": {
"iccid": "8901234567890123456",
"totalVolume": 8589934592,
"dataRemaining": 6442450944
}
}
{
"success": false,
"message": "Insufficient wallet balance",
"statusCode": 400
}
{
"success": false,
"message": "esimId is required for TOPUP package type",
"statusCode": 400
}
{
"success": false,
"message": "eSIM not found or does not belong to your account",
"statusCode": 404
}
Endpoint
POST /api/esim/buy
Description
Top up an existing eSIM with additional data. This uses the same purchase endpoint but withpackageType: 'TOPUP' and the esimId of the eSIM you want to refill.
Top-Up Flow
The complete top-up process follows these steps:1
Get your eSIMs
Call
GET /api/esim/my-esims to find the eSIM you want to top up. Note down its id and packageCode.2
Fetch top-up packages
Call
GET /api/esim/packages?type=TOPUP®ionCode={regionCode}&packageCode={packageCode} to see available top-up options.3
Get exchange rate (optional)
Call
GET /api/settings/exchange-rate to show the NGN equivalent price to your users.4
Purchase the top-up
Call
POST /api/esim/buy with packageType: 'TOPUP', the top-up packageCode, and the esimId.5
Verify the top-up
Call
GET /api/esim/{id} to confirm the updated data balance on the eSIM.Authentication
string
required
API Key for authentication
YOUR_API_KEY
Request Body
string
required
The top-up package code from the Get Top-Up Packages endpoint.
string
required
Payment method:
WALLET- Pay with wallet balance (instant)CARD- Pay with credit/debit cardBANK_TRANSFER- Pay via bank transfer
string
required
Must be
TOPUP for top-up purchases.string
required
The ID of the existing eSIM to top up. Get this from
GET /api/esim/my-esims.Response
string
Unique transaction ID for this top-up
string
Order status:
SUCCESS (wallet payment) or PENDING (card/bank transfer)object
Top-up package details
object
Example Request
curl -X POST https://api.vellosim.com/api/esim/buy \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"packageCode": "CKH384_TOPUP_3GB",
"paymentMethod": "WALLET",
"packageType": "TOPUP",
"esimId": "69125f9f56d7f09edabbaf23"
}'
async function topUpEsim(esimId, topupPackageCode) {
const response = await fetch('https://api.vellosim.com/api/esim/buy', {
method: 'POST',
headers: {
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
packageCode: topupPackageCode,
paymentMethod: 'WALLET',
packageType: 'TOPUP',
esimId: esimId
})
});
const data = await response.json();
if (data.status !== 'SUCCESS') {
throw new Error(data.message || 'Top-up failed');
}
return data;
}
// Usage
const result = await topUpEsim('69125f9f56d7f09edabbaf23', 'CKH384_TOPUP_3GB');
console.log(`Top-up successful! Transaction: ${result.transactionId}`);
import requests
def topup_esim(esim_id, topup_package_code):
"""Top up an existing eSIM with additional data"""
headers = {
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
}
payload = {
'packageCode': topup_package_code,
'paymentMethod': 'WALLET',
'packageType': 'TOPUP',
'esimId': esim_id
}
response = requests.post(
'https://api.vellosim.com/api/esim/buy',
headers=headers,
json=payload
)
data = response.json()
if data.get('status') != 'SUCCESS':
raise Exception(data.get('message', 'Top-up failed'))
return data
# Usage
result = topup_esim('69125f9f56d7f09edabbaf23', 'CKH384_TOPUP_3GB')
print(f"Top-up successful! Transaction: {result['transactionId']}")
<?php
function topUpEsim($esimId, $topupPackageCode) {
$apiKey = 'YOUR_API_KEY';
$payload = [
'packageCode' => $topupPackageCode,
'paymentMethod' => 'WALLET',
'packageType' => 'TOPUP',
'esimId' => $esimId
];
$ch = curl_init('https://api.vellosim.com/api/esim/buy');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-API-Key: ' . $apiKey,
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$data = json_decode($response, true);
curl_close($ch);
if ($data['status'] !== 'SUCCESS') {
throw new Exception($data['message'] ?? 'Top-up failed');
}
return $data;
}
// Usage
$result = topUpEsim('69125f9f56d7f09edabbaf23', 'CKH384_TOPUP_3GB');
echo "Top-up successful! Transaction: " . $result['transactionId'] . "\n";
?>
Example Response
{
"transactionId": "esim_1697888400_12345",
"status": "SUCCESS",
"message": "Top-up applied successfully",
"package": {
"packageCode": "CKH384_TOPUP_3GB",
"name": "USA Top-Up 3GB - 30 Days",
"price": 6.90,
"currencyCode": "USD",
"volume": 3221225472,
"duration": 30
},
"esimDetails": {
"iccid": "8901234567890123456",
"totalVolume": 8589934592,
"dataRemaining": 6442450944
}
}
{
"success": false,
"message": "Insufficient wallet balance",
"statusCode": 400
}
{
"success": false,
"message": "esimId is required for TOPUP package type",
"statusCode": 400
}
{
"success": false,
"message": "eSIM not found or does not belong to your account",
"statusCode": 404
}
Complete Top-Up Example
Here’s a full end-to-end example showing the entire top-up flow:async function completeTopUpFlow(esimId, regionCode, originalPackageCode) {
const headers = {
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
};
// Step 1: Get available top-up packages
const topupParams = new URLSearchParams({
type: 'TOPUP',
regionCode,
packageCode: originalPackageCode
});
const topupsRes = await fetch(
`https://api.vellosim.com/api/esim/packages?${topupParams}`,
{ headers }
);
const topups = await topupsRes.json();
if (topups.length === 0) {
console.log('No top-up options available for this eSIM');
return null;
}
console.log(`${topups.length} top-up options available:`);
topups.forEach((pkg, i) => {
const gb = (pkg.volume / 1073741824).toFixed(1);
console.log(` ${i + 1}. ${pkg.name}: ${gb}GB — $${pkg.price}`);
});
// Step 2: Get exchange rate for NGN display
const rateRes = await fetch(
'https://api.vellosim.com/api/settings/exchange-rate',
{ headers }
);
const { data: rateData } = await rateRes.json();
// Step 3: Select a top-up and show price
const selected = topups[0]; // Pick first option
const ngnPrice = Math.round(selected.price * rateData.rate * 100) / 100;
console.log(`\nSelected: ${selected.name} — $${selected.price} (≈ ₦${ngnPrice.toLocaleString()})`);
// Step 4: Purchase the top-up
const purchaseRes = await fetch('https://api.vellosim.com/api/esim/buy', {
method: 'POST',
headers,
body: JSON.stringify({
packageCode: selected.packageCode,
paymentMethod: 'WALLET',
packageType: 'TOPUP',
esimId
})
});
const result = await purchaseRes.json();
if (result.status === 'SUCCESS') {
console.log(`✅ Top-up applied! Transaction: ${result.transactionId}`);
} else {
console.log(`❌ Top-up failed: ${result.message}`);
}
return result;
}
// Usage
await completeTopUpFlow(
'69125f9f56d7f09edabbaf23', // esimId
'US', // regionCode
'CKH384' // original packageCode
);
Important Notes
Top-up requirements:
- The eSIM must be active — you cannot top up expired or cancelled eSIMs
- The top-up
packageCodemust be compatible with the original eSIM package - You must have sufficient wallet balance (for
WALLETpayment method)
Not all packages support top-ups. If
GET /api/esim/packages?type=TOPUP returns an empty array, the eSIM does not support data refills. The user would need to purchase a new eSIM instead.Next Steps
Get Top-Up Packages
Browse available top-up options
My eSIMs
Get your existing eSIMs
Check Balance
Check wallet balance before top-up
Top-Up Guide
Full integration guide
