API Reference#
Complete reference for the VPN Signal API endpoints.
Base URL#
Production: https://vpnsignal.io/api/v1Check IP#
Check if an IP address is associated with a VPN, Proxy, Tor, or hosting provider.
Endpoint#
POST /checkHeaders#
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer token with your API key |
Content-Type | Yes | Must be application/json |
Request Body#
json
{
"ip": "1.1.1.1"
}| Field | Type | Required | Description |
|---|---|---|---|
ip | string | Yes | IPv4 or IPv6 address to check |
Response#
json
{
"ip": "1.1.1.1",
"is_vpn": false,
"is_proxy": false,
"is_tor": false,
"is_relay": false,
"is_hosting": true,
"risk_score": 30,
"recommendation": "allow",
"company": {
"name": "Cloudflare, Inc.",
"type": "hosting",
"domain": "cloudflare.com"
},
"location": {
"country": "US",
"country_name": "United States",
"city": "San Francisco",
"region": "California",
"latitude": 37.7749,
"longitude": -122.4194
},
"asn": {
"number": 13335,
"name": "CLOUDFLARENET",
"route": "1.1.1.0/24"
}
}Response Fields#
| Field | Type | Description |
|---|---|---|
ip | string | The IP address that was checked |
is_vpn | boolean | True if IP belongs to a VPN provider |
is_proxy | boolean | True if IP is a known proxy server |
is_tor | boolean | True if IP is a Tor exit node |
is_relay | boolean | True if IP is an iCloud Private Relay |
is_hosting | boolean | True if IP is from a hosting/datacenter |
risk_score | integer | Risk score from 0-100 |
recommendation | string | allow, verify, or block |
company | object | Company information (if available) |
location | object | Geographic location data |
asn | object | Autonomous System Number data |
Note
Some fields like company, location, and asn may be null if the data is not available.
Example Request#
bash
curl -X POST https://vpnsignal.io/api/v1/check \
-H "Authorization: Bearer sk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{"ip": "104.28.231.47"}'Health Check#
Check if the API is running and healthy.
Endpoint#
GET /healthHeaders#
No authentication required.
Response#
json
{
"status": "healthy"
}Error Responses#
All errors follow a consistent format:
json
{
"error": "error_code",
"message": "Human-readable description",
"details": {}
}| HTTP Code | Error Code | Description |
|---|---|---|
| 400 | invalid_ip | The IP address format is invalid |
| 401 | unauthorized | Missing or invalid API key |
| 403 | forbidden | API key doesn't have access |
| 429 | rate_limit_exceeded | Daily limit exceeded |
| 500 | internal_error | Server error |
See Error Handling for detailed troubleshooting.
SDK Examples#
Node.js#
javascript
class VPNSignal {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://vpnsignal.io/api/v1';
}
async checkIP(ip) {
const response = await fetch(`${this.baseUrl}/check`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ ip }),
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message);
}
return response.json();
}
}
// Usage
const vpn = new VPNSignal('sk_live_abc123...');
const result = await vpn.checkIP('1.1.1.1');Python#
python
import requests
class VPNSignal:
def __init__(self, api_key):
self.api_key = api_key
self.base_url = 'https://vpnsignal.io/api/v1'
def check_ip(self, ip):
response = requests.post(
f'{self.base_url}/check',
headers={
'Authorization': f'Bearer {self.api_key}',
'Content-Type': 'application/json',
},
json={'ip': ip},
)
response.raise_for_status()
return response.json()
# Usage
vpn = VPNSignal('sk_live_abc123...')
result = vpn.check_ip('1.1.1.1')Rate Limits#
Rate limits are applied per API key:
| Plan | Daily Limit | Per-Second Limit |
|---|---|---|
| Free | 100 | 1 |
| Starter | 10,000 | 10 |
| Pro | 100,000 | 50 |
| Enterprise | Unlimited | 100 |
Rate limit headers are included in every response:
X-RateLimit-Limit: 10000
X-RateLimit-Remaining: 9523
X-RateLimit-Reset: 1640995200