API Documentation
Everything you need to integrate Auspex Verus™ IP classification into your application.
Quick Start
1. Get Your API Credentials
Sign up for an Auspex Verus™ account and generate your API key and secret from the portal.
API Key: alk_1234567890abcdef
API Secret: als_abcdefghijklmnopqrstuvwxyz1234567890
Important: Keep your API secret secure. It is used to sign requests and should never be transmitted directly.
2. Make Your First Request
Requests are authenticated using HMAC-SHA256 signatures. Each request requires:
- X-Amz-Date: Current timestamp in ISO 8601 basic format
- Authorization: HMAC-SHA256 signature header
# Example signed request (see code examples below for signature generation)
curl -X POST https://api.auspex-labs.com/verus/classify \
-H "Content-Type: application/json" \
-H "X-Amz-Date: 20250115T103000Z" \
-H "Authorization: HMAC-SHA256 Credential=alk_xxx/20250115/verus/aws4_request, SignedHeaders=x-amz-date, Signature=abc123..." \
-d '{"ipAddress": "8.8.8.8"}'
3. Handle the Response
The API returns a JSON response with classification results.
{
"human": false,
"certainty": 100
}
API Reference
Endpoint
Request Headers
| Header | Required | Description |
|---|---|---|
Content-Type |
Yes | Must be application/json |
X-Amz-Date |
Yes | Request timestamp in ISO 8601 basic format (YYYYMMDDTHHMMSSZ) |
Authorization |
Yes | HMAC-SHA256 signature (see Authentication section below) |
Authentication
Auspex Verus™ uses HMAC-SHA256 request signing. The Authorization header format is:
HMAC-SHA256 Credential={keyId}/{date}/verus/aws4_request, SignedHeaders={headers}, Signature={signature}
| Component | Description |
|---|---|
keyId |
Your API key (starts with alk_) |
date |
Date in YYYYMMDD format (must match X-Amz-Date) |
SignedHeaders |
Semicolon-separated lowercase header names: x-amz-date |
Signature |
Hex-encoded HMAC-SHA256 signature |
Request timestamps must be within 5 minutes of server time. Requests with expired timestamps will be rejected.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
ipAddress |
string | Yes | IPv4 or IPv6 address to classify |
Response Fields
| Field | Type | Description |
|---|---|---|
human |
boolean | true if likely human user, false if likely bot/automated traffic |
certainty |
integer | Confidence score from 0-100. Higher values indicate stronger confidence. |
Code Examples
Python
import hashlib
import hmac
import json
from datetime import datetime, timezone
import requests
API_KEY = "alk_1234567890abcdef"
API_SECRET = "als_abcdefghijklmnopqrstuvwxyz1234567890"
def sign_request(method, uri, body):
"""Generate HMAC-SHA256 signature for API request."""
amz_date = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
date_stamp = amz_date[:8]
# Derive signing key
k_date = hmac.new(f"AWS4{API_SECRET}".encode(), date_stamp.encode(), hashlib.sha256).digest()
k_service = hmac.new(k_date, b"verus", hashlib.sha256).digest()
k_signing = hmac.new(k_service, b"aws4_request", hashlib.sha256).digest()
# Create canonical request
signed_headers = "x-amz-date"
payload_hash = hashlib.sha256(body.encode()).hexdigest()
canonical_headers = f"x-amz-date:{amz_date}\n"
canonical_request = f"{method}\n{uri}\n\n{canonical_headers}\n{signed_headers}\n{payload_hash}"
# Create string to sign
credential_scope = f"{date_stamp}/verus/aws4_request"
request_hash = hashlib.sha256(canonical_request.encode()).hexdigest()
string_to_sign = f"HMAC-SHA256\n{amz_date}\n{credential_scope}\n{request_hash}"
# Compute signature
signature = hmac.new(k_signing, string_to_sign.encode(), hashlib.sha256).hexdigest()
authorization = f"HMAC-SHA256 Credential={API_KEY}/{credential_scope}, SignedHeaders={signed_headers}, Signature={signature}"
return {"Content-Type": "application/json", "X-Amz-Date": amz_date, "Authorization": authorization}
# Make request
body = json.dumps({"ipAddress": "8.8.8.8"})
headers = sign_request("POST", "/verus/classify", body)
response = requests.post("https://api.auspex-labs.com/verus/classify", headers=headers, data=body)
result = response.json()
print(f"Human: {result['human']}, Certainty: {result['certainty']}%")
JavaScript (Node.js)
const crypto = require('crypto');
const API_KEY = 'alk_1234567890abcdef';
const API_SECRET = 'als_abcdefghijklmnopqrstuvwxyz1234567890';
function signRequest(method, uri, body) {
const amzDate = new Date().toISOString().replace(/[-:]/g, '').split('.')[0] + 'Z';
const dateStamp = amzDate.slice(0, 8);
// Derive signing key
const kDate = crypto.createHmac('sha256', 'AWS4' + API_SECRET).update(dateStamp).digest();
const kService = crypto.createHmac('sha256', kDate).update('verus').digest();
const kSigning = crypto.createHmac('sha256', kService).update('aws4_request').digest();
// Create canonical request
const signedHeaders = 'x-amz-date';
const payloadHash = crypto.createHash('sha256').update(body).digest('hex');
const canonicalHeaders = `x-amz-date:${amzDate}\n`;
const canonicalRequest = `${method}\n${uri}\n\n${canonicalHeaders}\n${signedHeaders}\n${payloadHash}`;
// Create string to sign
const credentialScope = `${dateStamp}/verus/aws4_request`;
const requestHash = crypto.createHash('sha256').update(canonicalRequest).digest('hex');
const stringToSign = `HMAC-SHA256\n${amzDate}\n${credentialScope}\n${requestHash}`;
// Compute signature
const signature = crypto.createHmac('sha256', kSigning).update(stringToSign).digest('hex');
const authorization = `HMAC-SHA256 Credential=${API_KEY}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`;
return { amzDate, authorization };
}
async function classifyIP(ipAddress) {
const body = JSON.stringify({ ipAddress });
const { amzDate, authorization } = signRequest('POST', '/verus/classify', body);
const response = await fetch('https://api.auspex-labs.com/verus/classify', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Amz-Date': amzDate,
'Authorization': authorization
},
body
});
const result = await response.json();
console.log(`Human: ${result.human}, Certainty: ${result.certainty}%`);
return result;
}
classifyIP('8.8.8.8');
PHP
<?php
$apiKey = 'alk_1234567890abcdef';
$apiSecret = 'als_abcdefghijklmnopqrstuvwxyz1234567890';
$uri = '/verus/classify';
function signRequest($method, $uri, $body, $apiKey, $apiSecret) {
$amzDate = gmdate('Ymd\THis\Z');
$dateStamp = substr($amzDate, 0, 8);
// Derive signing key
$kDate = hash_hmac('sha256', $dateStamp, 'AWS4' . $apiSecret, true);
$kService = hash_hmac('sha256', 'verus', $kDate, true);
$kSigning = hash_hmac('sha256', 'aws4_request', $kService, true);
// Create canonical request
$signedHeaders = 'x-amz-date';
$payloadHash = hash('sha256', $body);
$canonicalHeaders = "x-amz-date:$amzDate\n";
$canonicalRequest = "$method\n$uri\n\n$canonicalHeaders\n$signedHeaders\n$payloadHash";
// Create string to sign
$credentialScope = "$dateStamp/verus/aws4_request";
$requestHash = hash('sha256', $canonicalRequest);
$stringToSign = "HMAC-SHA256\n$amzDate\n$credentialScope\n$requestHash";
// Compute signature
$signature = hash_hmac('sha256', $stringToSign, $kSigning);
$authorization = "HMAC-SHA256 Credential=$apiKey/$credentialScope, SignedHeaders=$signedHeaders, Signature=$signature";
return ['amzDate' => $amzDate, 'authorization' => $authorization];
}
$body = json_encode(['ipAddress' => '8.8.8.8']);
$sig = signRequest('POST', $uri, $body, $apiKey, $apiSecret);
$ch = curl_init("https://api.auspex-labs.com$uri");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'X-Amz-Date: ' . $sig['amzDate'],
'Authorization: ' . $sig['authorization']
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
$response = curl_exec($ch);
$result = json_decode($response, true);
echo "Human: " . ($result['human'] ? 'true' : 'false') . ", Certainty: " . $result['certainty'] . "%\n";
curl_close($ch);
C#
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
const string ApiKey = "alk_1234567890abcdef";
const string ApiSecret = "als_abcdefghijklmnopqrstuvwxyz1234567890";
const string Uri = "/verus/classify";
(string amzDate, string authorization) SignRequest(string method, string uri, string body)
{
var amzDate = DateTime.UtcNow.ToString("yyyyMMddTHHmmssZ");
var dateStamp = amzDate[..8];
// Derive signing key
var kDate = HmacSha256(Encoding.UTF8.GetBytes("AWS4" + ApiSecret), Encoding.UTF8.GetBytes(dateStamp));
var kService = HmacSha256(kDate, Encoding.UTF8.GetBytes("verus"));
var kSigning = HmacSha256(kService, Encoding.UTF8.GetBytes("aws4_request"));
// Create canonical request
var signedHeaders = "x-amz-date";
var payloadHash = Sha256Hex(body);
var canonicalHeaders = $"x-amz-date:{amzDate}\n";
var canonicalRequest = $"{method}\n{uri}\n\n{canonicalHeaders}\n{signedHeaders}\n{payloadHash}";
// Create string to sign
var credentialScope = $"{dateStamp}/verus/aws4_request";
var requestHash = Sha256Hex(canonicalRequest);
var stringToSign = $"HMAC-SHA256\n{amzDate}\n{credentialScope}\n{requestHash}";
// Compute signature
var signature = Convert.ToHexString(HmacSha256(kSigning, Encoding.UTF8.GetBytes(stringToSign))).ToLower();
var authorization = $"HMAC-SHA256 Credential={ApiKey}/{credentialScope}, SignedHeaders={signedHeaders}, Signature={signature}";
return (amzDate, authorization);
}
byte[] HmacSha256(byte[] key, byte[] data)
{
using var hmac = new HMACSHA256(key);
return hmac.ComputeHash(data);
}
string Sha256Hex(string data)
{
var hash = SHA256.HashData(Encoding.UTF8.GetBytes(data));
return Convert.ToHexString(hash).ToLower();
}
// Make request
var body = JsonSerializer.Serialize(new { ipAddress = "8.8.8.8" });
var (amzDate, authorization) = SignRequest("POST", Uri, body);
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, $"https://api.auspex-labs.com{Uri}");
request.Content = new StringContent(body, Encoding.UTF8, "application/json");
request.Headers.Add("X-Amz-Date", amzDate);
request.Headers.Add("Authorization", authorization);
var response = await client.SendAsync(request);
var result = await JsonSerializer.DeserializeAsync<JsonElement>(await response.Content.ReadAsStreamAsync());
Console.WriteLine($"Human: {result.GetProperty("human")}, Certainty: {result.GetProperty("certainty")}%");
Go
package main
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"net/http"
"time"
)
const (
apiKey = "alk_1234567890abcdef"
apiSecret = "als_abcdefghijklmnopqrstuvwxyz1234567890"
)
func signRequest(method, uri, body string) (string, string) {
amzDate := time.Now().UTC().Format("20060102T150405Z")
dateStamp := amzDate[:8]
// Derive signing key
kDate := hmacSHA256([]byte("AWS4"+apiSecret), []byte(dateStamp))
kService := hmacSHA256(kDate, []byte("verus"))
kSigning := hmacSHA256(kService, []byte("aws4_request"))
// Create canonical request
signedHeaders := "x-amz-date"
payloadHash := sha256Hex([]byte(body))
canonicalHeaders := fmt.Sprintf("x-amz-date:%s\n", amzDate)
canonicalRequest := fmt.Sprintf("%s\n%s\n\n%s\n%s\n%s", method, uri, canonicalHeaders, signedHeaders, payloadHash)
// Create string to sign
credentialScope := fmt.Sprintf("%s/verus/aws4_request", dateStamp)
requestHash := sha256Hex([]byte(canonicalRequest))
stringToSign := fmt.Sprintf("HMAC-SHA256\n%s\n%s\n%s", amzDate, credentialScope, requestHash)
// Compute signature
signature := hex.EncodeToString(hmacSHA256(kSigning, []byte(stringToSign)))
authorization := fmt.Sprintf("HMAC-SHA256 Credential=%s/%s, SignedHeaders=%s, Signature=%s",
apiKey, credentialScope, signedHeaders, signature)
return amzDate, authorization
}
func hmacSHA256(key, data []byte) []byte {
h := hmac.New(sha256.New, key)
h.Write(data)
return h.Sum(nil)
}
func sha256Hex(data []byte) string {
hash := sha256.Sum256(data)
return hex.EncodeToString(hash[:])
}
func main() {
body, _ := json.Marshal(map[string]string{"ipAddress": "8.8.8.8"})
amzDate, authorization := signRequest("POST", "/verus/classify", string(body))
req, _ := http.NewRequest("POST", "https://api.auspex-labs.com/verus/classify", bytes.NewBuffer(body))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Amz-Date", amzDate)
req.Header.Set("Authorization", authorization)
resp, _ := (&http.Client{}).Do(req)
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("Human: %v, Certainty: %.0f%%\n", result["human"], result["certainty"])
}
Bash (with OpenSSL)
#!/bin/bash
API_KEY="alk_1234567890abcdef"
API_SECRET="als_abcdefghijklmnopqrstuvwxyz1234567890"
URI="/verus/classify"
BODY='{"ipAddress": "8.8.8.8"}'
# Generate timestamp
AMZ_DATE=$(date -u +"%Y%m%dT%H%M%SZ")
DATE_STAMP=${AMZ_DATE:0:8}
# Helper function for HMAC-SHA256
hmac_sha256() {
local key="$1"
local data="$2"
echo -n "$data" | openssl dgst -sha256 -mac HMAC -macopt "$key" -binary
}
# Derive signing key
K_DATE=$(hmac_sha256 "key:AWS4${API_SECRET}" "$DATE_STAMP")
K_SERVICE=$(echo -n "verus" | openssl dgst -sha256 -mac HMAC -macopt "hexkey:$(echo -n "$K_DATE" | xxd -p -c 256)" -binary)
K_SIGNING=$(echo -n "aws4_request" | openssl dgst -sha256 -mac HMAC -macopt "hexkey:$(echo -n "$K_SERVICE" | xxd -p -c 256)" -binary)
K_SIGNING_HEX=$(echo -n "$K_SIGNING" | xxd -p -c 256)
# Create canonical request
SIGNED_HEADERS="x-amz-date"
PAYLOAD_HASH=$(echo -n "$BODY" | openssl dgst -sha256 | awk '{print $2}')
CANONICAL_HEADERS="x-amz-date:${AMZ_DATE}\n"
CANONICAL_REQUEST="POST\n${URI}\n\n${CANONICAL_HEADERS}\n${SIGNED_HEADERS}\n${PAYLOAD_HASH}"
REQUEST_HASH=$(echo -ne "$CANONICAL_REQUEST" | openssl dgst -sha256 | awk '{print $2}')
# Create string to sign
CREDENTIAL_SCOPE="${DATE_STAMP}/verus/aws4_request"
STRING_TO_SIGN="HMAC-SHA256\n${AMZ_DATE}\n${CREDENTIAL_SCOPE}\n${REQUEST_HASH}"
# Compute signature
SIGNATURE=$(echo -ne "$STRING_TO_SIGN" | openssl dgst -sha256 -mac HMAC -macopt "hexkey:${K_SIGNING_HEX}" | awk '{print $2}')
# Build authorization header
AUTHORIZATION="HMAC-SHA256 Credential=${API_KEY}/${CREDENTIAL_SCOPE}, SignedHeaders=${SIGNED_HEADERS}, Signature=${SIGNATURE}"
# Make request
curl -X POST "https://api.auspex-labs.com${URI}" \
-H "Content-Type: application/json" \
-H "X-Amz-Date: ${AMZ_DATE}" \
-H "Authorization: ${AUTHORIZATION}" \
-d "$BODY"
Error Handling
HTTP Status Codes
| Status | Meaning | Description |
|---|---|---|
200 |
Success | Classification completed successfully |
400 |
Bad Request | Invalid IP address format or missing required fields |
401 |
Unauthorized | Invalid or missing API credentials |
500 |
Server Error | Internal server error, contact support if persists |
Error Response Format
{
"error": "Invalid IP address format",
"statusCode": 400
}
Best Practices
Cache Results
Cache classification results for frequently seen IPs to reduce API calls and improve response times.
Use Certainty Scores
Don't just check human/bot - use certainty scores to implement nuanced policies (block high certainty bots, challenge medium certainty).
Secure Your Credentials
Never expose API keys in client-side code. Always make API calls from your backend server.
Monitor Usage
Track your API usage through the portal to avoid unexpected overage charges and optimize your plan.
Understanding Results
Interpreting Classifications
Human vs Bot
- human: true - IP is likely residential, mobile, or office network (legitimate user)
- human: false - IP is from hosting provider, datacenter, VPN, proxy, or known bot network
Certainty Levels
- 75-100 - High confidence, strong signal (act with confidence)
- 50-74 - Medium confidence, good signal (reasonable to act)
- 25-49 - Low confidence, weak signal (consider additional verification)
- 0-24 - Very low confidence, minimal signal (treat with caution)
Special Cases
-
Private IPs - RFC 1918 (10.x, 172.16.x, 192.168.x) and RFC 6598 (100.64.x) always return
{human: true, certainty: 0} - Certainty: 0 - Unable to classify with confidence (private IP or insufficient data)
Recommended Actions
| Classification | Certainty | Recommended Action |
|---|---|---|
| Bot | 75-100 | Block or present CAPTCHA |
| Bot | 50-74 | Challenge with CAPTCHA or additional verification |
| Bot | 0-49 | Allow with monitoring, apply rate limits |
| Human | Any | Allow with normal rate limits |
Support & Resources
Need Help?
Contact our support team for integration assistance, technical questions, or account issues.
Email:
support@auspex-labs.com
Try It Out
Test the Auspex Verus™ API with real IP addresses using our interactive demo interface.
Try DemoGitHub
Explore our open-source tools, report issues, and connect with other developers using Auspex Verus™.
View on GitHubReady to Try Auspex Verus™?
Experience real-time IP classification in action. Test our demo or get in touch to learn more.