Integrations → cURL / REST

cURL & raw REST reference

Protocol-level reference. Use this for Go, Ruby, Rust, Laravel, or any language that can make an HTTP request.

The one call you need

# Screen one visitor against the full ZeroBot pipeline
curl -s "https://api.zerobot.info/v3/openapi" \
  --data-urlencode "license=YOUR_LICENSE_KEY" \
  --data-urlencode "ip=8.8.8.8" \
  --data-urlencode "domain=yoursite.com" \
  --data-urlencode "useragent=Mozilla/5.0"

# → {"is_bot": true, "reason": "DATACENTER", "risk_score": 60, ...}

The API accepts GET or POST. For GET, pass parameters in the query string; for POST, use application/x-www-form-urlencoded.

Parameters

NameRequiredDescription
licenseYesYour license key from the ZeroBot dashboard.
ipYesVisitor IP (IPv4 or IPv6).
domainYesHost visitor is on. Must be in your account's authorized domains.
useragentRecommendedVisitor User-Agent header. Used by the heuristic layer.
allowed_countriesOptionalall or comma-separated ISO codes (e.g. US,GB,DE). Non-matching countries get is_bot=true, reason="Country Denied (XX)".
vpnOptional1 (default) blocks VPN traffic; 0 allows it.
datacenterOptional1 (default) blocks datacenter IPs; 0 allows them.

Response fields

{
  "username":     // encrypted account id (opaque)
  "is_bot":       // bool — final verdict
  "reason":       // e.g. "TOR", "VPN", "DATACENTER", "Country Denied (NL)", "ISP", "Clean"
  "risk_score":   // 0–100
  "country_code": // ISO 2-letter lowercase
  "country_name": // e.g. "United States"
  "asn":          // e.g. "AS15169"
  "isp":          // e.g. "Google LLC"
  "hostname":     // reverse DNS
  "tor":          // bool — is a Tor exit node
  "vpn":          // bool — matched a known VPN range
  "datacenter":   // bool — matched a known datacenter ASN
  "left":         // license days remaining
  "plan":         // plan name
}

Go example

package main

import (
    "encoding/json"
    "net/http"
    "net/url"
)

type Verdict struct {
    IsBot  bool   `json:"is_bot"`
    Reason string `json:"reason"`
}

func check(ip, ua string) (Verdict, error) {
    q := url.Values{
        "license":   {"YOUR_KEY"},
        "ip":        {ip},
        "domain":    {"yoursite.com"},
        "useragent": {ua},
    }
    r, err := http.Get("https://api.zerobot.info/v3/openapi?" + q.Encode())
    if err != nil { return Verdict{}, err }
    defer r.Body.Close()
    var v Verdict
    json.NewDecoder(r.Body).Decode(&v)
    return v, nil
}

Ruby example

require 'net/http'
require 'json'
require 'uri'

def zerobot_check(ip, ua)
  uri       = URI('https://api.zerobot.info/v3/openapi')
  uri.query = URI.encode_www_form(
    license:   ENV['ZEROBOT_KEY'],
    ip:        ip,
    domain:    'yoursite.com',
    useragent: ua
  )
  res = Net::HTTP.get_response(uri)
  JSON.parse(res.body) rescue {}
end

verdict = zerobot_check(request.remote_ip, request.user_agent)
halt 403, "Blocked: #{verdict['reason']}" if verdict['is_bot']

Error codes

HTTPMeaningMost likely cause
200OKNormal response. Inspect is_bot.
400Bad RequestMissing or invalid parameter. Check the error reason.
401UnauthorizedLicense key missing or invalid.
403ForbiddenUsually "Unauthorized domain" — the domain param isn't in your account's authorized list.
429Rate-limitedTemporary per-license cap reached. Back off for 60s.
5xxServer errorRare. Your client should fail open (treat as is_bot=false) and log.

More

Full endpoint catalog, auth reference, and the interactive tester live in the API Reference. For ready-made wrappers, see PHP, Node.js, Python, or drop in the WordPress plugin.