Agent Integration Examples

Copy-paste-ready code for every major agent framework and language

Plain PHP (no dependencies)

Simple examples using built-in PHP functions — no Composer or Guzzle needed:

PHP — file_get_contents
// Simplest possible fetch — one line
$params = http_build_query([
    'url'    => 'https://example.com',
    'apikey' => 'YOUR_KEY',
    'tag'    => 'my_script',
]);

$json = file_get_contents("https://www.botanon.com/api/fetch?{$params}");
$data = json_decode($json, true);

if ($data['success']) {
    echo $data['body'];  // The fetched HTML
    echo "\nProxy: " . $data['proxy']['driver'];
} else {
    echo "Error: " . $data['error'];
}
PHP — cURL
// cURL for more control (timeouts, POST, headers)
function botanon_fetch(string $url, string $apikey, string $tag = 'php_curl'): array {
    $params = http_build_query([
        'url'    => $url,
        'apikey' => $apikey,
        'tag'    => $tag,
        'ua'     => 'random',
    ]);

    $ch = curl_init("https://www.botanon.com/api/fetch?{$params}");
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 30,
        CURLOPT_FOLLOWLOCATION => true,
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($httpCode !== 200 || $response === false) {
        return ['success' => false, 'error' => "HTTP {$httpCode}"];
    }
    return json_decode($response, true);
}

// Usage
$result = botanon_fetch('https://example.com', 'YOUR_KEY');
echo $result['body'];
PHP — POST with cURL
$ch = curl_init('https://www.botanon.com/api/fetch');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode([
        'url'       => 'https://api.example.com/search',
        'apikey'    => 'YOUR_KEY',
        'method'    => 'POST',
        'post_data' => json_encode(['query' => 'AI agents']),
        'post_type' => 'json',
        'tag'       => 'search',
    ]),
]);

$data = json_decode(curl_exec($ch), true);
curl_close($ch);
echo $data['body'];

Claude Code / MCP Tool

Use BotAnon as a fetch tool in your MCP server or Claude Code skill. Here's a complete PHP function for an MCP server:

PHP — MCP Server Fetch Tool
// Example: PHP function an MCP server could use
function botanon_fetch(string $url, string $tag = 'claude_agent'): array {
    $client = new \GuzzleHttp\Client();
    $response = $client->get('https://www.botanon.com/api/fetch', [
        'query' => [
            'url' => $url,
            'apikey' => getenv('BOTANON_API_KEY'),
            'tag' => $tag,
            'ua' => 'random',
        ],
        'timeout' => 30,
    ]);
    return json_decode((string)$response->getBody(), true);
}
Python — MCP Server Fetch Tool
import os
import requests

def botanon_fetch(url: str, tag: str = "claude_agent") -> dict:
    """Fetch a URL through BotAnon for anonymous access."""
    resp = requests.get("https://www.botanon.com/api/fetch", params={
        "url": url,
        "apikey": os.environ["BOTANON_API_KEY"],
        "tag": tag,
        "ua": "random",
    }, timeout=30)
    resp.raise_for_status()
    data = resp.json()
    if not data["success"]:
        raise Exception(f"BotAnon error: {data.get('error', 'unknown')}")
    return data

Hermes / Autonomous Agents

Autonomous agents that scrape multiple URLs can loop through BotAnon with built-in rate limiting and error handling:

Python — Autonomous Agent Loop
import requests
import time

BOTANON_API = "https://www.botanon.com/api/fetch"
API_KEY = "YOUR_KEY"

def agent_fetch(url, tag="hermes_agent"):
    resp = requests.get(BOTANON_API, params={
        "url": url,
        "apikey": API_KEY,
        "tag": tag,
        "ua": "random",
    })
    data = resp.json()
    if data["success"]:
        return data["body"]
    raise Exception(f"Fetch failed: {data.get('error', 'unknown')}")

# Agent workflow example
urls = [
    "https://example.com/pricing",
    "https://example.com/about",
    "https://example.com/contact",
]

for url in urls:
    html = agent_fetch(url)
    # Process html with your LLM...
    print(f"Fetched {url}: {len(html)} bytes")
    time.sleep(1)  # Be respectful

Node.js / TypeScript Agents

Modern Node.js with the built-in fetch API — no dependencies needed:

JavaScript — Node.js Agent
const BOTANON_API = 'https://www.botanon.com/api/fetch';

async function agentFetch(url, tag = 'node_agent') {
  const params = new URLSearchParams({
    url, apikey: process.env.BOTANON_API_KEY, tag, ua: 'random'
  });
  const resp = await fetch(`${BOTANON_API}?${params}`);
  const data = await resp.json();
  if (!data.success) throw new Error(data.error);
  return data;
}

// Use in your agent
const result = await agentFetch('https://example.com');
console.log(`HTTP ${result.http_code}, ${result.body_size} bytes via ${result.proxy.driver}`);

cURL / Shell Scripts

Quick command-line examples for testing or shell-based agent workflows:

Bash — Simple GET
curl -s 'https://www.botanon.com/api/fetch?url=https://example.com&apikey=YOUR_KEY&tag=shell' | jq .
Bash — POST with JSON data
curl -s -X POST https://www.botanon.com/api/fetch \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://api.example.com/search","apikey":"YOUR_KEY","method":"POST","post_data":"{\"q\":\"test\"}","post_type":"json"}' | jq .
Bash — With compression
curl -s --compressed 'https://www.botanon.com/api/fetch?url=https://example.com&apikey=YOUR_KEY&compress=1' | jq .
Bash — Browser rendering (JS-heavy pages)
curl -s 'https://www.botanon.com/api/fetch?url=https://spa-app.com&apikey=YOUR_KEY&browser=1' | jq .body

Advanced: POST Data & Custom Headers

BotAnon supports form POSTs, JSON POSTs, and custom headers for complex API interactions:

Python — Form POST
resp = requests.post("https://www.botanon.com/api/fetch", json={
    "url": "https://example.com/login",
    "apikey": "YOUR_KEY",
    "method": "POST",
    "post_data": "username=agent&password=secret",
    "post_type": "form",
    "tag": "login_agent",
})
data = resp.json()
print(data["body"])
Python — JSON POST
import json

resp = requests.post("https://www.botanon.com/api/fetch", json={
    "url": "https://api.example.com/search",
    "apikey": "YOUR_KEY",
    "method": "POST",
    "post_data": json.dumps({"query": "AI agents", "limit": 10}),
    "post_type": "json",
    "tag": "search_agent",
})
data = resp.json()
print(data["body"])
PHP — Custom User-Agent & Timeout
$response = $client->get('https://www.botanon.com/api/fetch', [
    'query' => [
        'url'     => 'https://tough-target.com',
        'apikey'  => 'YOUR_KEY',
        'ua'      => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/125.0.0.0',
        'timeout' => 60,
        'browser' => 1,
        'tag'     => 'tough_target',
    ],
]);

Error Handling Best Practice

Always check the success field, implement retries with backoff, and use tags for debugging:

Python — Retry with Backoff
import requests
import time

def resilient_fetch(url, tag="my_agent", max_retries=3):
    """Fetch with automatic retries and exponential backoff."""
    for attempt in range(max_retries):
        try:
            resp = requests.get("https://www.botanon.com/api/fetch", params={
                "url": url,
                "apikey": API_KEY,
                "tag": f"{tag}_attempt_{attempt}",
                "ua": "random",
                "refresh": 1 if attempt > 0 else 0,  # Force fresh on retry
            }, timeout=30)
            data = resp.json()

            if data["success"]:
                return data

            # Non-retryable errors
            if data.get("http_code") in [404, 401, 403]:
                return data  # Don't retry client errors

        except requests.RequestException as e:
            print(f"Request error: {e}")

        if attempt < max_retries - 1:
            wait = 2 ** attempt  # 1s, 2s, 4s
            print(f"Retrying in {wait}s...")
            time.sleep(wait)

    raise Exception(f"Failed after {max_retries} attempts: {url}")
PHP — Error Handling
function safe_fetch(string $url, string $tag): ?array {
    try {
        $client = new \GuzzleHttp\Client();
        $response = $client->get('https://www.botanon.com/api/fetch', [
            'query' => [
                'url'    => $url,
                'apikey' => getenv('BOTANON_API_KEY'),
                'tag'    => $tag,
            ],
            'timeout' => 30,
        ]);
        $data = json_decode((string)$response->getBody(), true);

        if (!$data['success']) {
            error_log("BotAnon fetch failed [{$tag}]: " . ($data['error'] ?? 'unknown'));
            return null;
        }
        return $data;

    } catch (\Throwable $e) {
        error_log("BotAnon exception [{$tag}]: " . $e->getMessage());
        return null;
    }
}

Google Maps API

Search places, look up details, and queue or instant-run crawls.

🔍 Search Places

# Simple search — returns ~20 places
curl "https://www.botanon.com/api/gmaps/search?apikey=KEY&query=bars+Derby"

# Deep search with forced tier
curl "https://www.botanon.com/api/gmaps/search?apikey=KEY&query=pubs+York&depth=5&tier=residential&refresh=1"

📍 Place Lookup

# Get details for a known place_id
curl "https://www.botanon.com/api/gmaps/place/0x2fb4e9b346dee95b:0xd5811e26f15ce74d?apikey=KEY"

🚀 Crawl — Queue Mode

# Add to crawl queue with high priority
curl -X POST https://www.botanon.com/api/gmaps/crawl \
  -H 'Content-Type: application/json' \
  -d '{
    "apikey": "KEY",
    "query": "pest_control in Sevenoaks, Kent, GB",
    "mode": "queue",
    "priority": 1,
    "region": "Kent",
    "category": "pest_control"
  }'

# Auto-detect location/category from query string
curl -X POST https://www.botanon.com/api/gmaps/crawl \
  -H 'Content-Type: application/json' \
  -d '{"apikey": "KEY", "query": "plumbers in Bristol, GB"}'

⚡ Crawl — Instant Mode

# Get results immediately (10-60 seconds)
curl -X POST https://www.botanon.com/api/gmaps/crawl \
  -H 'Content-Type: application/json' \
  -d '{
    "apikey": "KEY",
    "query": "restaurants in Albufeira, PT",
    "mode": "instant",
    "depth": 3
  }'

📍 Crawl by Place ID

# Crawl the area around a known place (derives location + category)
curl -X POST https://www.botanon.com/api/gmaps/crawl \
  -H 'Content-Type: application/json' \
  -d '{
    "apikey": "KEY",
    "place_id": "ChIJqfzVUcwEdkgR7cvsVYJ8daE"
  }'

# Override category — find restaurants near a pub's location
curl -X POST https://www.botanon.com/api/gmaps/crawl \
  -H 'Content-Type: application/json' \
  -d '{
    "apikey": "KEY",
    "place_id": "ChIJqfzVUcwEdkgR7cvsVYJ8daE",
    "category": "restaurant",
    "priority": 2
  }'
# → Derives: "restaurant in London, GB"

🐍 Python — GMaps Crawl

import requests

# Queue with high priority
resp = requests.post("https://www.botanon.com/api/gmaps/crawl", json={
    "apikey": "KEY",
    "query": "electricians in Cardiff, GB",
    "mode": "queue",
    "priority": 1,
    "region": "Cardiff",
})
data = resp.json()
print(f"Queued: #{data['queue_id']} at priority {data['priority']}")

# Instant scrape
resp = requests.post("https://www.botanon.com/api/gmaps/crawl", json={
    "apikey": "KEY",
    "query": "dentists in Oxford, GB",
    "mode": "instant",
    "depth": 3,
})
data = resp.json()
print(f"Found {data['places_count']} places in {data['duration_seconds']:.1f}s")

🐘 PHP — GMaps Crawl

// Queue a crawl
$ch = curl_init('https://www.botanon.com/api/gmaps/crawl');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode([
        'apikey'   => 'KEY',
        'query'    => 'roofers in Leeds, GB',
        'mode'     => 'queue',
        'priority' => 2,
        'region'   => 'Leeds',
        'category' => 'roofers',
    ]),
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
echo "Queue ID: {$data['queue_id']}\n";

Twitter/X Search API

Search Twitter/X via authenticated cookie-based accounts. Results cached 24h.

🐦 Search Tweets

curl -X POST https://www.botanon.com/api/twitter-search \
  -H 'Content-Type: application/json' \
  -d '{
    "apikey": "KEY",
    "q": "faro airport queue OR delay OR busy -filter:retweets",
    "max": 10
  }'

🐍 Python — Twitter Search

import requests

resp = requests.post("https://www.botanon.com/api/twitter-search", json={
    "apikey": "KEY",
    "q": "faro airport queue OR delay since:2026-05-01",
    "max": 10,
})
data = resp.json()
for tweet in data.get("tweets", []):
    print(f"@{tweet['author']}: {tweet['text'][:80]}")

👤 Manage Accounts

# Add account (cookies from Chrome DevTools → x.com)
curl -X POST https://www.botanon.com/api/twitter-search \
  -H 'Content-Type: application/json' \
  -d '{
    "apikey": "KEY",
    "action": "add-account",
    "username": "myxaccount",
    "auth_token": "abc123...",
    "ct0": "xyz789..."
  }'

# List loaded accounts
curl -X POST https://www.botanon.com/api/twitter-search \
  -H 'Content-Type: application/json' \
  -d '{"apikey": "KEY", "action": "accounts"}'