Analytics export
Exclusive to the Business ($49/mo) plan: pull 5-minute batch rollups via GET /v1/analytics/export OR receive true real-time event streaming (0ms delay) via GET /v1/analytics/stream and live_stream_webhook_url to join pseudonymous user identifiers against your local database.
Business ($49/mo) Plan Feature: Why Zero-Trust User Correlation Matters
Plan Requirement: Programmatic access to GET /v1/analytics/export is included exclusively with the Business ($49/mo) plan (Upgrade to Business). Calling this endpoint with a Starter or Builder key returns HTTP 403 pro_plan_required.
Gated operates on a strict zero-retention privacy model: we never see or store your end-users' email addresses, names, or raw prompt text. However, as an application owner, you often want to know which specific user accounts on your platform are attempting prompt-extraction attacks, coupon exploits, or token-drain paste bombs so your internal admin dashboard can flag, rate-limit, or suspend them.
With GET /v1/analytics/export, you get both privacy and full visibility:
- Zero PII Sent to Gated: When your backend calls
POST /v1/check, you pass an opaque pseudonymous identifier in theuserfield (for example,usr_8f92a1c4or"usr_" + sha256(user.id + LOCAL_SALT).slice(0, 16)). Gated only ever sees that opaque token. - Two Access Modes: 5-Minute Batch Pull + True Real-Time Event Streaming: Use
GET https://getgated.ai/v1/analytics/exportfor scheduled 5-minute batch pulls (min_poll_interval_seconds: 300), OR useGET https://getgated.ai/v1/analytics/stream(SSE / instant stream with0scooldown) and configurelive_stream_webhook_urlviaPOST /v1/analytics/streamso every blocked or flagged prompt is pushed to your server in real time (0msdelay) the instant it occurs. - Local Join Inside Your Own Backend: Your server caches the export response for 5 minutes and joins
abusive_users_rollup[].customer_user_ref(oruser_hash) against your own localuserstable. Your internal admin panel displays the exact user email and account details while keeping 100% of customer PII inside your own database.
Step 1: Pass a Pseudonymous user Identifier to POST /v1/check
Generate a deterministic pseudonymous reference on your server (or store a gate_user_ref column on your users table) and pass it in the user field when calling POST /v1/check:
import crypto from "node:crypto";
// Deterministic pseudonymous user token (never exposes email or raw UUID to Gated)
export function toGateUserRef(userId: string): string {
const salt = process.env.INTERNAL_USER_HASH_SALT || "app_local_salt";
return "usr_" + crypto.createHmac("sha256", salt).update(String(userId)).digest("hex").slice(0, 16);
}
// Inside your chat route before calling OpenAI / Anthropic:
const gateUserRef = toGateUserRef(currentUser.id);
const gateRes = await fetch("https://getgated.ai/v1/check", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.M6L_GATE_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
user: gateUserRef,
input: userMessage,
feature: "chat",
}),
signal: AbortSignal.timeout(400),
});Step 2: Fetch & Cache GET /v1/analytics/export (5-Minute Cooldown)
Call GET https://getgated.ai/v1/analytics/export from your backend and cache the result for 5 minutes (300 seconds). If your backend calls the endpoint again before 300 seconds have elapsed, Gated returns HTTP 429 Too Many Requests with a Retry-After header indicating how many seconds remain until the next allowed poll.
curl -sS https://getgated.ai/v1/analytics/export \
-H "Authorization: Bearer $M6L_GATE_KEY"Example 200 OK Response
{
"ok": true,
"schema_version": "1.0",
"app_id": "app_15ad7beb3e6593de",
"fetched_at": "2026-10-25T13:00:00.000Z",
"min_poll_interval_seconds": 300,
"next_allowed_fetch_at": "2026-10-25T13:05:00.000Z",
"polling_policy": "Maximum 1 fetch every 5 minutes (300 seconds) per API key. Cache this payload in your backend or database for 5 minutes.",
"summary": {
"total_checks": 42,
"blocked_count": 5,
"flagged_count": 1,
"allowed_count": 36,
"estimated_tokens_saved": 4820,
"estimated_usd_saved": 0.0723
},
"abusive_users_rollup": [
{
"user_hash": "9d81a24f0c11b3e9a01244c1",
"user_key": "usr_a8f921c4e0",
"customer_user_ref": "usr_a8f921c4e0",
"total_requests": 6,
"blocked_attempts": 4,
"flagged_attempts": 0,
"allowed_attempts": 2,
"categories_triggered": ["secret_extraction", "ecom_discount_abuse"],
"rule_ids_triggered": ["INJ.01", "SEC.01", "ECOM.DISCOUNT.01"],
"estimated_tokens_saved": 3910,
"estimated_usd_saved": 0.0587,
"first_seen_at": 1761396000000,
"last_seen_at": 1761396900000,
"recommended_action": "rate_limit_or_suspend"
}
],
"events_count": 42,
"events": [ ... ]
}Step 3: Join Against Your Local users Table in Your Admin Backend
Here is a complete Next.js / Node server helper that caches the Gated export for 5 minutes and joins abusive_users_rollup with your own database users:
let cachedExport: { data: any; expiresAt: number } | null = null;
export async function getCorrelatedAbusiveUsers(dbUsers: Array<{ id: string; email: string; name: string }>) {
const now = Date.now();
if (!cachedExport || now >= cachedExport.expiresAt) {
const res = await fetch("https://getgated.ai/v1/analytics/export", {
headers: { Authorization: `Bearer ${process.env.M6L_GATE_KEY}` },
});
if (res.ok) {
const payload = await res.json();
cachedExport = { data: payload, expiresAt: now + 300_000 }; // Cache for 5 minutes (300s)
} else if (!cachedExport) {
throw new Error(`Gated export returned HTTP ${res.status}`);
}
}
// Build local lookup map from pseudonymous gate_user_ref -> real internal user record
const userByRef = new Map(dbUsers.map((u) => [toGateUserRef(u.id), u]));
return (cachedExport.data.abusive_users_rollup || []).map((row: any) => ({
...row,
local_user: userByRef.get(row.customer_user_ref) || null,
}));
}One-Click AI Builder Prompt (Claude, ChatGPT, Grok Bot, Lovable, Cursor)
Copy and paste this prompt into your AI coding assistant to add an internal Abusive Users & Token Drain Leaderboard to your own admin dashboard:
Add an internal "AI Abuse & Token Drain Protection" panel to my admin dashboard powered by Gated:
1. In our AI chat backend route, before calling POST https://getgated.ai/v1/check, pass a deterministic pseudonymous user token in the "user" field: "usr_" + HMAC_SHA256(user.id, INTERNAL_SALT).slice(0, 16) so we never send raw user emails or PII to Gated.
2. Create an internal admin backend endpoint that fetches GET https://getgated.ai/v1/analytics/export with header Authorization: Bearer process.env.M6L_GATE_KEY.
3. IMPORTANT: Gated enforces a 5-minute (300-second) cooldown between /v1/analytics/export fetches per API key (min_poll_interval_seconds: 300). Cache the response in memory or our database for 5 minutes (300 seconds) and never poll more frequently than once every 5 minutes.
4. Join response.abusive_users_rollup[].customer_user_ref against our local users table and render an admin table showing the user email, blocked_attempts, categories_triggered, estimated_usd_saved, and recommended_action ("flag_for_review" or "rate_limit_or_suspend").