REST API
Toolvico API Documentation
Build OTP activations and SMM ordering directly into your product. The API returns JSON, uses wallet billing in USD, and is protected by account API keys.
https://toolvico.com/api/v1application/jsonX-API-KeyAuthentication
Send your API key with every request using the X-API-Key header. Generate and manage keys from Dashboard -> API Access.
curl "https://toolvico.com/api/v1/otp?action=balance" \
-H "X-API-Key: your_api_key_here"
Rate Limits
API keys are limited to 60 requests per minute per endpoint. A rate limited response returns HTTP 429 with a Retry-After header.
Get Countries
/api/v1/otp?action=countries
Return available OTP countries for a provider server type.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
type |
integer | No | Provider server type, 1-5. Defaults to 1. |
Request Example
curl -X GET "https://toolvico.com/api/v1/otp?action=countries&type=1" \
-H "X-API-Key: your_api_key_here"
$ctx = stream_context_create(['http' => ['header' => "X-API-Key: your_api_key_here\r\n"]]);
$response = file_get_contents('https://toolvico.com/api/v1/otp?action=countries&type=1', false, $ctx);
$data = json_decode($response, true);
const res = await fetch('/api/v1/otp?action=countries&type=1', {
headers: { 'X-API-Key': 'your_api_key_here' }
});
const { data } = await res.json();
console.log(data.countries);
Response
{
"success": true,
"data": {
"countries": [
{ "id": "61", "name": "Pakistan" },
{ "id": "21", "name": "India" }
]
}
}
Get Services
/api/v1/otp?action=services
List OTP services for a country with your marked-up USD price.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
country_id |
string | Yes | Country ID from the countries endpoint. |
type |
integer | No | Provider server type, 1-5. Defaults to 1. |
Request Example
curl -X GET "https://toolvico.com/api/v1/otp?action=services&country_id=61&type=1" \
-H "X-API-Key: your_api_key_here"
$url = 'https://toolvico.com/api/v1/otp?action=services&country_id=61&type=1';
$ctx = stream_context_create(['http' => ['header' => "X-API-Key: your_api_key_here\r\n"]]);
$data = json_decode(file_get_contents($url, false, $ctx), true);
const res = await fetch('/api/v1/otp?action=services&country_id=61&type=1', {
headers: { 'X-API-Key': 'your_api_key_here' }
});
const { data } = await res.json();
Response
{
"success": true,
"data": {
"services": [
{ "service_id": "306343", "name": "discord", "your_price_usd": 0.040000 }
]
}
}
Buy Number
/api/v1/otp?action=buy_number
Purchase an OTP number. Wallet is charged only if the provider returns a number.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
service_id |
string | Yes | Service ID from get services. |
country_id |
string | Yes | Country ID. |
type |
integer | No | Provider server type. Defaults to 1. |
Request Example
curl -X POST "https://toolvico.com/api/v1/otp?action=buy_number" \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"service_id":"306343","country_id":"61","type":1}'
$payload = json_encode(['service_id' => '306343', 'country_id' => '61', 'type' => 1]);
$ctx = stream_context_create(['http' => ['method' => 'POST', 'header' => "X-API-Key: your_api_key_here\r\nContent-Type: application/json\r\n", 'content' => $payload]]);
$data = json_decode(file_get_contents('https://toolvico.com/api/v1/otp?action=buy_number', false, $ctx), true);
const res = await fetch('/api/v1/otp?action=buy_number', {
method: 'POST',
headers: { 'X-API-Key': 'your_api_key_here', 'Content-Type': 'application/json' },
body: JSON.stringify({ service_id: '306343', country_id: '61', type: 1 })
});
const { data } = await res.json();
Response
{
"success": true,
"data": {
"order_id": "42",
"phone_number": "+923001234567",
"status": "waiting"
}
}
Get Status
/api/v1/otp?action=get_status
Poll an OTP order until it returns waiting, received, or cancelled.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
order_id |
integer | Yes | Database order ID returned by buy number. |
Request Example
curl -X GET "https://toolvico.com/api/v1/otp?action=get_status&order_id=42" \
-H "X-API-Key: your_api_key_here"
$ctx = stream_context_create(['http' => ['header' => "X-API-Key: your_api_key_here\r\n"]]);
$data = json_decode(file_get_contents('https://toolvico.com/api/v1/otp?action=get_status&order_id=42', false, $ctx), true);
const res = await fetch('/api/v1/otp?action=get_status&order_id=42', {
headers: { 'X-API-Key': 'your_api_key_here' }
});
const { data } = await res.json();
Response
{
"success": true,
"data": { "status": "received", "code": "123456" }
}
Cancel
/api/v1/otp?action=cancel
Cancel a waiting OTP order after the minimum waiting period and refund wallet balance.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
order_id |
integer | Yes | Database order ID. |
Request Example
curl -X POST "https://toolvico.com/api/v1/otp?action=cancel" \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"order_id":42}'
$payload = json_encode(['order_id' => 42]);
$ctx = stream_context_create(['http' => ['method' => 'POST', 'header' => "X-API-Key: your_api_key_here\r\nContent-Type: application/json\r\n", 'content' => $payload]]);
$data = json_decode(file_get_contents('https://toolvico.com/api/v1/otp?action=cancel', false, $ctx), true);
const res = await fetch('/api/v1/otp?action=cancel', {
method: 'POST',
headers: { 'X-API-Key': 'your_api_key_here', 'Content-Type': 'application/json' },
body: JSON.stringify({ order_id: 42 })
});
Response
{
"success": true,
"data": { "refunded": true, "amount": "0.040000" }
}
Balance
/api/v1/otp?action=balance
Return your API wallet balance in USD.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
none |
- | No | No parameters required. |
Request Example
curl -X GET "https://toolvico.com/api/v1/otp?action=balance" \
-H "X-API-Key: your_api_key_here"
$ctx = stream_context_create(['http' => ['header' => "X-API-Key: your_api_key_here\r\n"]]);
$data = json_decode(file_get_contents('https://toolvico.com/api/v1/otp?action=balance', false, $ctx), true);
const res = await fetch('/api/v1/otp?action=balance', {
headers: { 'X-API-Key': 'your_api_key_here' }
});
const { data } = await res.json();
Response
{
"success": true,
"data": { "wallet_balance": "12.450000", "currency": "USD" }
}
List Services
/api/v1/smm?action=services
Return active SMM services with marked-up USD rates per 1000 units.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
none |
- | No | No parameters required. |
Request Example
curl -X GET "https://toolvico.com/api/v1/smm?action=services" \
-H "X-API-Key: your_api_key_here"
$ctx = stream_context_create(['http' => ['header' => "X-API-Key: your_api_key_here\r\n"]]);
$data = json_decode(file_get_contents('https://toolvico.com/api/v1/smm?action=services', false, $ctx), true);
const res = await fetch('/api/v1/smm?action=services', {
headers: { 'X-API-Key': 'your_api_key_here' }
});
const { data } = await res.json();
Response
{
"success": true,
"data": {
"services": [
{ "service_id": "1", "name": "Followers", "category": "Instagram", "rate_usd_per_1000": 1.08, "min": 50, "max": 10000 }
]
}
}
Place Order
/api/v1/smm?action=place_order
Create an SMM order and deduct wallet balance after provider acceptance.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
service_id |
string | Yes | SMM service ID. |
link |
string | Yes | Target URL/profile/video. |
quantity |
integer | Yes | Quantity within service min and max. |
Request Example
curl -X POST "https://toolvico.com/api/v1/smm?action=place_order" \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"service_id":"1","link":"https://instagram.com/user","quantity":500}'
$payload = json_encode(['service_id' => '1', 'link' => 'https://instagram.com/user', 'quantity' => 500]);
$ctx = stream_context_create(['http' => ['method' => 'POST', 'header' => "X-API-Key: your_api_key_here\r\nContent-Type: application/json\r\n", 'content' => $payload]]);
$data = json_decode(file_get_contents('https://toolvico.com/api/v1/smm?action=place_order', false, $ctx), true);
const res = await fetch('/api/v1/smm?action=place_order', {
method: 'POST',
headers: { 'X-API-Key': 'your_api_key_here', 'Content-Type': 'application/json' },
body: JSON.stringify({ service_id: '1', link: 'https://instagram.com/user', quantity: 500 })
});
const { data } = await res.json();
Response
{
"success": true,
"data": { "order_id": "15", "charged": 0.540000, "status": "Pending" }
}
Order Status
/api/v1/smm?action=order_status
Poll SMM order status and sync start count, remains, and partial refunds.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
order_id |
integer | Yes | Database order ID returned by place order. |
Request Example
curl -X GET "https://toolvico.com/api/v1/smm?action=order_status&order_id=15" \
-H "X-API-Key: your_api_key_here"
$ctx = stream_context_create(['http' => ['header' => "X-API-Key: your_api_key_here\r\n"]]);
$data = json_decode(file_get_contents('https://toolvico.com/api/v1/smm?action=order_status&order_id=15', false, $ctx), true);
const res = await fetch('/api/v1/smm?action=order_status&order_id=15', {
headers: { 'X-API-Key': 'your_api_key_here' }
});
const { data } = await res.json();
Response
{
"success": true,
"data": { "status": "Partial", "remains": 157, "start_count": 3572 }
}
Balance
/api/v1/smm?action=balance
Return your API wallet balance in USD.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
none |
- | No | No parameters required. |
Request Example
curl -X GET "https://toolvico.com/api/v1/smm?action=balance" \
-H "X-API-Key: your_api_key_here"
$ctx = stream_context_create(['http' => ['header' => "X-API-Key: your_api_key_here\r\n"]]);
$data = json_decode(file_get_contents('https://toolvico.com/api/v1/smm?action=balance', false, $ctx), true);
const res = await fetch('/api/v1/smm?action=balance', {
headers: { 'X-API-Key': 'your_api_key_here' }
});
const { data } = await res.json();
Response
{
"success": true,
"data": { "wallet_balance": "12.450000", "currency": "USD" }
}
Error Codes
| Code | Meaning | How to handle |
|---|---|---|
| 401 | Invalid or missing API key | Check the X-API-Key header. |
| 402 | Insufficient wallet balance | Top up via dashboard. |
| 403 | API access not enabled | Enable API access in dashboard settings. |
| 404 | Order or service not found | Check the ID parameter. |
| 429 | Rate limit exceeded | Retry after 60 seconds. |
| 503 | Provider unavailable | Retry later. Failed provider purchases are refunded. |
Code Examples
These examples buy a number and poll until an OTP is received or cancelled.
PHP
final class OTPFlowClient {
public function __construct(private string $baseUrl, private string $apiKey) {}
public function request(string $path, array $body = null): array {
$opts = ['http' => ['header' => "X-API-Key: {$this->apiKey}\r\nContent-Type: application/json\r\n"]];
if ($body !== null) {
$opts['http']['method'] = 'POST';
$opts['http']['content'] = json_encode($body);
}
$json = file_get_contents($this->baseUrl . $path, false, stream_context_create($opts));
return json_decode($json, true);
}
}
$client = new OTPFlowClient('https://toolvico.com/api/v1', 'your_api_key_here');
$order = $client->request('/otp?action=buy_number', ['service_id' => '306343', 'country_id' => '61', 'type' => 1]);
$orderId = $order['data']['order_id'];
for ($i = 0; $i < 20; $i++) {
sleep(6);
$status = $client->request('/otp?action=get_status&order_id=' . $orderId);
if (($status['data']['status'] ?? '') === 'received') {
echo $status['data']['code'];
break;
}
}
JavaScript
const apiKey = 'your_api_key_here';
async function api(path, body) {
const res = await fetch('/api/v1' + path, {
method: body ? 'POST' : 'GET',
headers: { 'X-API-Key': apiKey, 'Content-Type': 'application/json' },
body: body ? JSON.stringify(body) : undefined
});
const json = await res.json();
if (!json.success) throw new Error(json.error);
return json.data;
}
const order = await api('/otp?action=buy_number', {
service_id: '306343', country_id: '61', type: 1
});
const timer = setInterval(async () => {
const status = await api('/otp?action=get_status&order_id=' + order.order_id);
if (status.status === 'received') {
clearInterval(timer);
console.log('OTP:', status.code);
}
}, 6000);