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. Pass server/provider_source for one public server, or omit it to merge enabled route sources.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
server |
string | No | Public server: romeo, juliet, peter, paul, andrew, mark, luke, john, or all. provider_source/source are also accepted aliases. |
Request Example
curl -X GET "https://toolvico.com/api/v1/otp?action=countries" \
-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', false, $ctx);
$data = json_decode($response, true);
const res = await fetch('/api/v1/otp?action=countries', {
headers: { 'X-API-Key': 'your_api_key_here' }
});
const { data } = await res.json();
console.log(data.countries);
Response
{
"success": true,
"data": {
"countries": [
{ "id": "61", "key": "pakistan", "name": "Pakistan", "routes": [{"provider_type":1,"country_id":"61"}], "providers": ["peter"], "provider_country_ids": {"peter": ["61"]} },
{ "id": "13", "key": "unitedstates", "name": "USA", "providers": ["romeo"], "provider_country_ids": {"romeo": ["13", "188"]} }
],
"provider_sources": ["romeo", "juliet", "peter", "paul", "andrew", "mark", "luke", "john"]
}
}
Get Services
/api/v1/otp?action=services
List OTP services with marked-up USD prices. Pass server/provider_source plus country_id for one public server, or pass country_key and routes for all enabled route sources.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
country_id |
string | Conditional | Route country ID. Required for single-source calls. |
server |
string | No | Public server: romeo, juliet, peter, paul, andrew, mark, luke, john, or all. provider_source/source are also accepted aliases. |
provider_type |
integer | No | Route server type for peter. Default 1. |
country_key |
string | No | Merged country key from countries endpoint. |
routes |
string | No | Comma-separated peter routes like 1:61,2:61. |
Request Example
curl -X GET "https://toolvico.com/api/v1/otp?action=services&country_key=pakistan&routes=1:61" \
-H "X-API-Key: your_api_key_here"
$url = 'https://toolvico.com/api/v1/otp?action=services&country_key=pakistan&routes=1:61';
$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_key=pakistan&routes=1:61', {
headers: { 'X-API-Key': 'your_api_key_here' }
});
const { data } = await res.json();
Response
{
"success": true,
"data": {
"services": [
{ "service_id": "306343", "name": "Discord", "provider_source": "peter", "country_id": "61", "provider_type": 1, "your_price_usd": 0.040000, "success_rate": 86 },
{ "service_id": "tg", "name": "Telegram", "provider_source": "paul", "country_id": "6", "provider_type": 0, "your_price_usd": 0.180000, "success_rate": 91 }
],
"provider_sources": ["romeo", "juliet", "peter", "paul", "andrew", "mark", "luke", "john"]
}
}
Buy Number
/api/v1/otp?action=buy_number
Purchase an OTP number. Wallet is charged only if the route returns a number. Use server/provider_source, country_id, provider_type, and pool_id exactly as returned by get services.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
service_id |
string | Yes | Service ID from get services. |
country_id |
string | Yes | Route country ID from get services. |
server |
string | No | Public server from get services. Default peter. provider_source/source are also accepted aliases. |
provider_type |
integer | No | Route server type for peter. Default 1. |
pool_id |
string | No | Pool ID when server is andrew. |
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","server":"peter","provider_type":1}'
$payload = json_encode(['service_id' => '306343', 'country_id' => '61', 'server' => 'peter', 'provider_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', server: 'peter', provider_type: 1 })
});
const { data } = await res.json();
Response
{
"success": true,
"data": {
"order_id": "42",
"phone_number": "+923001234567",
"provider_source": "peter",
"charged_usd": 0.04,
"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']);
$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'
});
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);