Reference

Agent API

This is the REST JSON protocol used by AuraGuardian agents (PHP/Node/Python/Shopify/etc.). All responses are JSON. Server-side agents receive an encrypted payload; browser agents receive a decision response.

Base URL

Base URL: https://auraguardian.co/api

Agent Contract

Agents may include optional identity fields (Agent Contract v1). The server accepts these fields but does not require them.

  • protocol_version: integer (v1 is 1)
  • agent_kind: php-thin|node|python|shopify|go|java|dotnet|edge
  • agent_version: string (e.g. 2.8.0)
  • capabilities: string[] (e.g. enforce:block, telemetry:v1)

POST /verify

Verifies a license, enforces subscription + plan constraints, tracks domain usage, and returns either an encrypted ruleset or a Shopify browser decision. The response also uses version stamps so agents only receive heavy payloads (global IP list, intel lists) when they changed.

POST /verify

Request body

{
  "license_key": "UP_LIVE_...",
  "domain": "example.com",
  "blocked_ips_version": 1710000000,
  "intel_version": 1,

  "protocol_version": 1,
  "agent_kind": "php-thin",
  "agent_version": "2.8.0",
  "capabilities": ["enforce:block", "telemetry:v1"]
}
  • domain is normalized server-side (strip protocol, www., ports, etc.).
  • blocked_ips_version is compared to the server’s latest blocked_ips.max(updated_at) timestamp.
  • intel_version is compared to system_meta.intel_version.

Server-agent success response

{
  "status": "success",
  "timestamp": 1710000000,
  "encrypted": true,
  "payload": "BASE64(IV[16] + CIPHERTEXT + HMAC-SHA256[32])"
}

Shopify browser-agent decision response

{
  "status": "success",
  "action": "allow|challenge|block",
  "reason": "Challenge",
  "reason_code": "challenge",
  "risk_score": 70,
  "ip": "203.0.113.10",
  "challenge_url": "https://auraguardian.co/security-check?token=..."
}

Verify status codes

  • 401 {status:"error"}: invalid license key
  • 403 {status:"suspended"}: license exists but is not active
  • 200 {status:"expired"}: subscription expired beyond grace period (agent should disable protection)
  • 200 {status:"success", payload:null}: domain limit reached / blocked domain (upgrade required)
  • 200 {status:"success", action:"allow|challenge|block"}: Shopify browser-agent decision

POST /log

Stores telemetry in access_logs. Some reasons/actions trigger auto-ban into the global blocked_ips list.

POST /log

Request body

{
  "license_key": "UP_LIVE_...",
  "ip": "1.2.3.4",
  "action": "BLOCK",
  "reason": "SQL Injection",
  "user_agent": "Mozilla/5.0...",
  "country": "US",

  "protocol_version": 1,
  "agent_kind": "node",
  "agent_version": "0.10.2",
  "capabilities": ["telemetry:v1"]
}

POST /challenge/init

Creates an opaque challenge token used to redirect clients to /security-check without leaking license_key and return_url in query strings.

POST /challenge/init

Request body

{
  "license_key": "UP_LIVE_...",
  "return_url": "https://example.com/checkout"
}

Success response

{
  "status": "success",
  "token": "BASE64(iv + cipher + mac)",
  "ttl": 300
}

Encryption

The rules payload returned by /verify is encrypted using AES-256-CBC. The key is derived from the license key: SHA-256(license_key) as raw bytes. The payload format is: base64_encode(iv(16) + ciphertext + hmac_sha256(32)). The HMAC key is derived from SHA-256(license_key + ':hmac').

Versioned payloads

To avoid resending large lists on every sync:

  • blocked_ips_version: if unchanged, server returns global_blocked_ips: null and agent should keep cache.
  • intel_version: if unchanged, server returns intel keys as null and agent should keep cache.

Rate limits

Agent endpoints are protected by a hardened limiter:

  • 60 requests / minute / IP
  • 120 requests / minute / license_key

Runtime examples

These examples show the intended integration shape for upcoming multi-runtime SDKs.

Node (Express)

import express from "express";
import { ultimateProtectorExpress } from "@auraprotector/agent/express";

const app = express();

app.use(ultimateProtectorExpress({
  licenseKey: "UP_LIVE_...",
  apiUrl: "https://auraguardian.co/api",
}));

app.get("/", (req, res) => res.send("ok"));
app.listen(3000);

Python (ASGI/FastAPI)

from fastapi import FastAPI
from auraprotector_agent.asgi import UltimateProtectorMiddleware

app = FastAPI()

app.add_middleware(
    UltimateProtectorMiddleware,
    license_key="UP_LIVE_...",
    api_url="https://auraguardian.co/api",
)

@app.get("/")
def root():
    return {"ok": True}