# ZOV SDK 0.2
Base URL: https://api.zov.lat/v1. Keys go only in Authorization: Bearer. HTTPS is mandatory.
Choose permissions per integration; never embed real keys in distributed client applications.
Unknown values are null, not false. ZOV, ML and account policy are separate. REVIEW means no matching policy; decide how to handle it explicitly.

## Python (standard library)
Import sdk/python/zov.py. Read ZOV_API_KEY from environment. Example:
```python
import os
from zov import Zov
client = Zov(os.environ["ZOV_API_KEY"])
print(client.lookup("8.8.8.8"))
```
See constructor in source for optional base URL and timeout. No extra Python package needed.

## TypeScript / JavaScript
Compile typescript/zov.ts with TypeScript targeting ES2022, or import from a TypeScript project.
Use Zov with a server-side environment key. Browser applications must use their own short-lived server session instead of a shared secret.

## Rust
Use a path dependency on rust/ (crate zov-sdk). Tokio async runtime required.
Use Zov::new and lookup/batch/call methods; structured API errors include HTTP status.

## Java 17+
Compile java/Zov.java with javac --release 17. No external dependency needed.
HttpClient sends only JSON requests over HTTPS. Parse response JSON with your application JSON library.

## Minecraft Paper
Built for Paper 1.21.4 API and Java 21+. Copy zov-antiproxy-paper-0.2.0.jar to plugins/, restart, then configure the plugin config.yml. Store API key in ZOV_API_KEY environment variable or in a protected config file.
Default: observation only (enforce-policy false), fail-open true. To enforce account DENY policies explicitly enable enforce-policy. UNKNOWN/REVIEW never causes automatic blocking. Tor/VPN matching alone does not equal policy DENY.
Async login checks have a 1500 ms timeout, a bounded concurrency limit, a 60-second cache and a maximum 10000 cache entries.
The plugin never scans IP ranges or connects to proxies.
Build: Maven package in minecraft/. Runtime integration needs your own Paper server; build/API checks do not certify every server version.

## API examples
GET /ip/8.8.8.8?fields=ip,asn,geo,vpn,proxy,tor,policy_verdict
POST /ip/batch {"ips":["8.8.8.8","2001:4860:4860::8888"],"fields":["ip","asn"]}
GET /ip?limit=50&country=RU; next page: pass meta.pagination.next_cursor as cursor.
GET /exports/ip?format=ndjson&limit=1000 needs exports:create and ip:read.
Errors: 401 invalid key/session, 403 scope, 422 validation, 429 quota, 503 dependency. Back off on 429/503, keep bounded retries, and don't replace unknown with clean.
Per-key defaults: 60/min,10000/day,100000/month. Batch also limited to 5/min and 50 inputs. Refresh 10/min. Exports 10/hour and1000 rows.

## Webhook verification
Raw JSON body + X-Zov-Timestamp. Expected X-Zov-Signature is sha256=HMAC_SHA256(secret, timestamp+"."+raw_body). Constant-time compare, reject timestamp outside 5 minutes, deduplicate X-Zov-Event-Id. Five delivery attempts with exponential backoff. New signing secret shown once. Redirects and internal/reserved DNS addresses forbidden.

## GeoIP attribution
IP Geolocation by DB-IP: https://db-ip.com, DB-IP Country Lite CC BY 4.0, reduced accuracy, no city. Preserve attribution when displaying geography from this API.

Minecraft events: set collect-events=true and asset-id to your authorized asset UUID; the API key requires events:write. Event delivery is bounded to eight asynchronous requests, contains no player name/UUID/chat, and does not block login. HTTP transport peer addresses behind protection are infrastructure observations; forwarded headers are not accepted as verified client IPs.
