API Documentation
Everything you need to integrate VaultAcc into your platform. Base URL: /api/v1
Authentication
All API requests require your API key sent as a request header. Get your key from the API Access page.
Never expose your API key in client-side JavaScript. Always make API calls from your server.
// Add this header to every request
headers: {
'X-API-Key': 'vl_your_api_key_here'
}
Rate Limits
The API is rate-limited per API key. Exceeding the limit returns HTTP 429.
| Limit | Window | Scope |
|---|---|---|
| 60 requests | Per minute | Per API key |
| 50 items | Per buy request | Max log_ids per order |
| 20 purchases | Per 15 minutes | Buy endpoint only |
Response Format
Every response is JSON with a
success boolean. On error, a message field explains what went wrong.Success
{ "success": true, "data": [ ... ] }
Error
{ "success": false, "message": "Insufficient balance." }
List Categories
Returns all active categories and how many groups are available in each. Use category slugs to filter the groups endpoint.
GET
/api/v1/categories
Auth required
Response Fields
id
number
Category ID
name
string
Display name e.g. "Facebook"
slug
string
Use this in ?category= filter
icon
string
Emoji icon for the category
description
string
Category description
available_groups
number
Groups with stock right now
Response
{
"success": true,
"data": [
{
"id": 1,
"name": "Facebook",
"slug": "facebook",
"icon": "📘",
"description": "Verified Facebook accounts",
"available_groups": 12
}
]
}
List Groups
Returns available listings. Filter by category, country, or type. All fields needed to display a product card to your customers are included.
GET
/api/v1/groups
Auth required
Query Parameters
| Param | Type | Required | Description |
|---|---|---|---|
| category | string | Optional | Category slug e.g. facebook |
| country | string | Optional | 2-letter country code e.g. NG, US |
| type | string | Optional | log or tutorial — default: log |
| page | number | Optional | Page number, default: 1 |
| limit | number | Optional | Per page, max 100, default: 20 |
Response Fields
id
number
Group ID — use this to fetch items
title
string
Listing title to show customers
description
string | null
Full listing description with details
platform
string
e.g. "facebook", "instagram"
country
string
Full country name e.g. "Nigeria"
country_code
string
2-letter code e.g. "NG"
price_per_item
number
Price in Naira per account
quantity_available
number
Stock remaining right now
quantity_total
number
Total stock ever uploaded
category
string
Category name
category_slug
string
Category slug
category_icon
string
Category emoji icon
Example Request
fetch('/api/v1/groups?category=facebook&country=US&limit=10', {
headers: { 'X-API-Key': 'vl_your_key' }
})
Response
{
"success": true,
"data": [
{
"id": 42,
"title": "USA Facebook Accounts — SMS Verified",
"description": "Aged accounts verified by SMS. Include email:password and cookies. Ready to use.",
"platform": "facebook",
"country": "United States",
"country_code": "US",
"price_per_item": 1500,
"quantity_available": 48,
"quantity_total": 100,
"category": "Facebook",
"category_slug": "facebook",
"category_icon": "📘"
}
],
"total": 48,
"page": 1
}
Get Group Detail New
Fetch full details for a single group by its ID. Useful when you want to show a product detail page to your customers before they buy.
GET
/api/v1/groups/:id
Auth required
URL Parameter
| Param | Type | Description |
|---|---|---|
| id | number | The group ID from the list endpoint |
Response
{
"success": true,
"data": {
"id": 42,
"title": "USA Facebook Accounts — SMS Verified",
"description": "Aged accounts verified by SMS. Include email:password and cookies.",
"platform": "facebook",
"country": "United States",
"country_code": "US",
"price_per_item": 1500,
"quantity_available": 48,
"quantity_total": 100,
"category": "Facebook",
"category_slug": "facebook",
"category_icon": "📘",
"created_at": "2024-06-01T10:22:00.000Z"
}
}
Preview Items in a Group
Returns available item IDs and a short preview snippet for each. The full
log_content is never exposed here — it is only returned after a successful purchase.
GET
/api/v1/groups/:id/items
Auth required
Query Parameters
| Param | Type | Required | Description |
|---|---|---|---|
| limit | number | Optional | How many items to return, max 100, default 50 |
Response
{
"success": true,
"count": 50,
"data": [
{
"id": 1801,
"profile_url": "https://facebook.com/61574354041804",
"preview": "john.doe@gma••••••"
}
]
}
Use the id values from this response as your
log_ids when calling the buy endpoint. Fetch enough items to cover how many your customer wants to buy.
Get Wallet Balance
Returns your current wallet balance in Naira. Check this before placing large orders.
GET
/api/v1/balance
Auth required
Response
{ "success": true, "balance": 24500.00 }
Purchase Logs
Purchase one or more log items in a single atomic transaction. Full
content is returned immediately in the response. Your wallet is debited and stock is updated in the same operation — no partial failures.
POST
/api/v1/buy
Auth required
Request Body (JSON)
| Field | Type | Required | Description |
|---|---|---|---|
| log_ids | number[] | Required | Array of item IDs from /groups/:id/items. Min 1, max 50. |
Example Request
fetch('/api/v1/buy', {
method: 'POST',
headers: {
'X-API-Key': 'vl_your_key',
'Content-Type': 'application/json'
},
body: JSON.stringify({ log_ids: [1801, 1802, 1803] })
})
Response Fields
order_ref
string
Your order reference number
total_paid
number
Total Naira deducted
new_balance
number
Your wallet balance after purchase
item_count
number
Number of items purchased
logs[].log_id
number
Item ID
logs[].content
string
Full log content — deliver this to your customer
logs[].group_title
string
The listing title this item came from
logs[].platform
string
Platform name
logs[].price
number
Price paid per item
Response
{
"success": true,
"order_ref": "API-1718291234-X9KA",
"total_paid": 4500,
"new_balance": 20000,
"item_count": 3,
"logs": [
{
"log_id": 1801,
"group_title": "USA Facebook Accounts — SMS Verified",
"platform": "facebook",
"content": "john.doe@gmail.com|Password123|...",
"price": 1500
}
]
}
Guide: Complete Buy Flow
The recommended sequence for browsing and purchasing logs through the API end-to-end.
const BASE = 'https://vaultacc.com'; // your VaultAcc base URL
const headers = {
'X-API-Key': 'vl_your_key',
'Content-Type': 'application/json'
};
// Step 1 — Get categories (optional but useful for UI)
const cats = await fetch(`${BASE}/api/v1/categories`, { headers }).then(r => r.json());
// Step 2 — List available groups
const groups = await fetch(`${BASE}/api/v1/groups?category=facebook&limit=20`, { headers }).then(r => r.json());
const group = groups.data[0];
console.log(group.title); // "USA Facebook Accounts — SMS Verified"
console.log(group.description); // "Aged accounts verified by SMS..."
console.log(group.price_per_item); // 1500
// Step 3 — Get item IDs from that group (decide how many to buy)
const qty = 5; // customer wants 5
const itemsRes = await fetch(`${BASE}/api/v1/groups/${group.id}/items?limit=${qty}`, { headers }).then(r => r.json());
const log_ids = itemsRes.data.slice(0, qty).map(i => i.id);
// Step 4 — Check balance before buying (optional safety check)
const balRes = await fetch(`${BASE}/api/v1/balance`, { headers }).then(r => r.json());
const cost = group.price_per_item * qty;
if (balRes.balance < cost) throw new Error('Top up your VaultAcc wallet first.');
// Step 5 — Purchase
const order = await fetch(`${BASE}/api/v1/buy`, {
method: 'POST', headers,
body: JSON.stringify({ log_ids })
}).then(r => r.json());
// Step 6 — Deliver content to your customer
order.logs.forEach(log => {
console.log(log.content); // full account data — deliver this
});
console.log(`New balance: ₦${order.new_balance}`);
Guide: Reseller Setup
If you're building a reseller site on top of VaultAcc, here's the recommended architecture so your customers can browse and buy smoothly.
Always call the VaultAcc API from your server, never from the browser. Your API key must stay private. Your customers should talk to your server, which talks to VaultAcc.
Recommended flow:
1. Your server caches
2. When a customer clicks "Buy", your server calls
3. Your server immediately calls
4. Never store raw log content longer than needed to deliver it to your customer.
1. Your server caches
/api/v1/groups every few minutes and serves it to your customers — this saves API calls and makes your site fast.2. When a customer clicks "Buy", your server calls
/api/v1/groups/:id/items?limit=N to get N item IDs.3. Your server immediately calls
/api/v1/buy with those IDs and returns the content to the customer.4. Never store raw log content longer than needed to deliver it to your customer.
// Example: Express reseller server endpoint
app.post('/buy', async (req, res) => {
const { group_id, quantity } = req.body;
// 1. Get item IDs
const itemsRes = await fetch(
`${VAULTACC_BASE}/api/v1/groups/${group_id}/items?limit=${quantity}`,
{ headers: { 'X-API-Key': process.env.VAULTACC_KEY } }
).then(r => r.json());
if (!itemsRes.success || itemsRes.data.length < quantity) {
return res.status(400).json({ error: 'Not enough stock.' });
}
const log_ids = itemsRes.data.slice(0, quantity).map(i => i.id);
// 2. Purchase from VaultAcc
const order = await fetch(`${VAULTACC_BASE}/api/v1/buy`, {
method: 'POST',
headers: {
'X-API-Key': process.env.VAULTACC_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({ log_ids })
}).then(r => r.json());
if (!order.success) {
return res.status(400).json({ error: order.message });
}
// 3. Return content to your customer
res.json({ items: order.logs.map(l => l.content) });
});
Error Reference
All errors return a consistent JSON body with a human-readable message.
| Status | Meaning | What to do |
|---|---|---|
| 400 | Bad request | Check your request parameters or body |
| 401 | Unauthorized | Check your X-API-Key header |
| 403 | Forbidden | Account suspended — contact support |
| 404 | Not found | Group or item doesn't exist or is inactive |
| 429 | Rate limited | Wait and retry — max 60 req/min |
| 500 | Server error | Retry once; contact support if it persists |
{ "success": false, "message": "Insufficient balance. Need ₦3000, have ₦1500." }
Webhooks — Overview
VaultAcc sends real-time POST requests to your server when events happen, such as when your wallet is funded.
Your endpoint must respond with HTTP 200 within 10 seconds. Failed deliveries are retried 3 times with exponential backoff.
// Minimal Express.js webhook receiver
app.post('/webhook/vaultacc', express.raw({ type: 'application/json' }), (req, res) => {
const payload = JSON.parse(req.body.toString());
res.sendStatus(200); // Always respond 200 first
switch (payload.event) {
case 'payment_received':
// Credit the user on your platform
break;
}
});
Webhook Events
payment_received
Fired when a user successfully funds their wallet via bank transfer. The wallet is credited automatically.
order_completed
Fired when a purchase completes through the API. Contains the order reference and items purchased.
Payload structure
{
"event": "payment_received",
"timestamp": "2024-06-13T14:22:00Z",
"data": {
"transaction_id": "TXN-29381920",
"amount": 5000,
"settlement": 4950,
"customer": {
"email": "user@example.com",
"account_number": "0123456789"
}
}
}
Webhook Verification
Verify the
X-VaultAcc-Signature header on every incoming webhook to confirm the request is genuinely from VaultAcc.
const crypto = require('crypto');
function verifyWebhook(rawBody, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature)
);
}
const sig = req.headers['x-vaultacc-signature'];
const secret = process.env.VAULTACC_WEBHOOK_SECRET;
if (!verifyWebhook(req.body, sig, secret)) {
return res.sendStatus(401);
}