Launching soon: public registration, pricing and new checkouts are closed. Launch updates: https://nightsec.io/launch. Contact: info@nightsec.io. # Nightsec integration guide (API v1) Nightsec serves observed proxy intelligence. An unknown IP is not proof of safety. Demo records are labeled synthetic=true. Provider, classification, confidence and country are operator/source assertions; confidence is not a probability. Location is enriched from the configured local IP2Location LITE database. location is null until available. geolocation reports status, source, database_date, database_stale (older than 90 days), updated_at and CC BY-SA 4.0 attribution. Coordinates are approximate exit-IP locations, not end-user positions. Geo updates do not change proxy sighting timestamps. Most recent attribution wins in the current record; previous sightings remain in event history. ## Authentication Register at /register, sign in, create a key at /dashboard. Send Authorization: Bearer . Never send credentials in URLs or public JavaScript. Keys are shown once, hashed at rest, independently revocable. Administrator operations require an admin browser session, which API keys cannot provide. ## Machine-readable interface GET /openapi.json is the public customer API contract. /api-docs is the interactive reference. /docs is the human guide. API failures return JSON {"detail":...}. Admin or billing mutations require explicit user authorization when invoked by agents. ## Lookups GET /v1/lookup/{ip}: canonical IPv4/IPv6. found=false means no current observation. Found responses include ip, provider, classification (proxy/vpn/tor/hosting/residential), confidence (0..100), country (two letters or empty), first_seen/last_seen (Unix seconds UTC), active, synthetic, source_id (nullable). Only observations newer than the configured TTL are returned (30 days default). POST /v1/lookup body {"ips":["203.0.113.42","2001:db8::42"]}: 1..100 IPs. Returns {"results":[...]}. Charges one unit per IP, including duplicates and unknown addresses, atomically. Invalid bodies are not charged. GET /v1/me: account plan, billing status, UTC month, used and quota. ## Plans and limits Developer/free: 1000 IP lookups per UTC calendar month, no downloads/streaming. Pro: 100000 lookups/month, downloads and streams. Business: 1000000 lookups/month, downloads and streams. 600 API requests per minute per account, plus 30 SSE connection starts per minute. Up to 10 active keys. Stream events and downloads do not consume lookup quota. Quotas stop requests without charging overage. 401 invalid key; 403 missing entitlement/role; 404 missing release; 409 resource conflict; 422 malformed input; 429 quota/rate limit (Retry-After); 502/503 temporary dependency failure or missing configuration. ## Local snapshots GET /v1/releases/latest (paid): {id,created_at,cursor,count,schema_version:1,files:{"iplens.mmdb":{sha256,bytes,url},"iplens.jsonl":{sha256,bytes,url}}}. Download relative file URL from the same API origin using the bearer header. GET /v1/releases/{id}/manifest.json also downloads the manifest. Validate SHA256, then atomically replace the database. A generic MaxMind DB reader is required; this custom IPLens-Proxy schema is not GeoIP2 city data. Python: import maxminddb; with maxminddb.open_database('iplens.mmdb') as db: print(db.get('203.0.113.42')). Missing address returns null. Supports IPv4 and IPv6. Only active records are in a snapshot. Published artifacts are immutable. MMDB cannot be modified in place. ## Changes and HTTP streaming Bootstrap a snapshot and retain its cursor. GET /v1/events?after=CURSOR&limit=100 returns {events,next_cursor,has_more}. Maximum limit 1000. Cursor is exclusive. Page until has_more=false. Store cursor after successfully applying each event. Each event is {id,operation,data,observed_at}; data is the full observation. Operation is upsert or delete. Deletes deactivate and must suppress entries in the base snapshot. GET /v1/stream?after=CURSOR returns SSE with bearer auth. Reconnect using Last-Event-ID, which is combined with after by taking the larger value. Events have id, event:upsert/delete and JSON data. Persist cursor only after applying an event. Delivery is at least once: deduplicate by ID. Maintain an overlay with tombstones for deletes; regenerate or replace the immutable MMDB periodically. Connections end after 55 seconds, with an event:reconnect control frame containing the last cursor. Comments are heartbeats; event:access_revoked terminates revoked access. Retry after 2 seconds with exponential backoff on failures. once=true returns one page of up to 100 events for diagnostics. Events are retained indefinitely in this prototype. Snapshot records and cursor are captured in one serialized transaction; ingestion commits are serialized to avoid cursor commit reordering. ## Billing Prices are USD/month: Pro $49; Business $199. Operator must configure matching recurring Stripe prices. POST /billing/checkout {plan:"pro"|"business"} and POST /billing/portal require a same-origin browser session. Only current Stripe active/trialing subscription state grants paid access. Past_due, unpaid, paused, incomplete and canceled fall back to free. Cancel-at-period-end stays active until Stripe changes status. Signed webhooks at /webhook (alias /billing/webhook) are idempotent and retrieve current subscription state. Redirects do not grant access. ## Data operations Admins configure HTTP CONNECT, SOCKS4 or SOCKS5 proxy probes with operator-owned credentials. Manual observations and HTTP list collection are retired. Run now queues the source for the separate collector. Proxy DNS is validated and pinned; Production uses an operator-owned authenticated /probe/exit HTTPS receiver with nonce validation; local development may use https://ifconfig.me/ip. Email login uses single-use eight-digit codes, ten-minute expiry, five attempts per code, and request/verification rate limits. No password login exists. Zoho Mail API (OAuth refresh) or TLS SMTP configuration is required in production; local-only outbox delivery is not production email. GET /health is database-backed liveness. GET /health/ready additionally checks worker freshness in production. GET /status reports the last 24 hours of recorded independent monitor checks; absent samples are unknown. Monitor can check authenticated GET /v1/me using a dedicated API key without consuming lookup quota. Configure an off-host monitor as well. Admin request analytics retain client IP, account/key ID, route, response status, latency and sanitised Referer/Origin headers for 30 days by default. No credentials, request bodies or header query strings are stored. Referer and Origin are unverified, optional client reports and do not prove where an API key was used. Proxy forwarding headers are accepted only from the configured trusted reverse proxy. Administrator plan overrides are explicit and independent of Stripe billing; Follow billing removes the override. Deactivation blocks existing API keys, retires browser sessions and denies email-code sign-in. Admin provider charts count first sightings per provider/IP, not repeated probes or geo updates. Audience summaries show visitor IPs, countries and reported referral domains over seven days, excluding API traffic and recognized bot/CLI user agents. IPs are not people and this filter cannot prove human traffic. The audit trail is paginated. Customers may remove revoked keys from their console list using POST /console/keys/{id}/dismiss. Only the owner can dismiss a key, and it must already be revoked. Removal hides its row; it remains revoked and its audit history is retained. Operations filters and pagination preserve the other filters; customer filters use effective access plans, including overrides and deactivation. ## Prepared security intelligence category No DDoS-for-hire or stresser feed is connected. GET /v1/security/{ip} is a separate authenticated, metered endpoint (one lookup unit). It returns current source-attributed associations, evidence types (service_advertisement, third_party_report, observed_attack), named services, source URLs/references and observation/expiry times. `proxy_observation` contains a current non-synthetic exact-IP proxy overlap if one exists. Neither overlap nor service advertising proves malicious activity. Empty associations do not establish safety. No security risk score is assigned. This category is not included in proxy MMDB exports or proxy SSE events. Nightsec retains existing IPLENS_ operator configuration names, cookie names, download filenames and the IPLens-Proxy schema identifier for integration compatibility. New API keys use the nsec_ prefix; previously issued keys remain valid. Customer examples use NIGHTSEC_API_KEY; the example sync client also accepts the earlier IPLENS_API_KEY variable.