Bot Protection
Call the check-request API from your server or CDN to get allow, block, or challenge for each request. You can start with a minimal body (ip, trustedId, requestedPath) and optionally add headers and cookies for stronger detection.
Quickstart: call the endpoint (minimal body)
Call POST /api/v1/check-request with your secret in the Authorization header and a JSON body with:
ip(required) — client IP (e.g. fromx-forwarded-foror your connection).trustedId(optional) — session/visitor ID from thetrusted_idcookie or a previous API response.requestedPath(optional) — path the user requested (e.g./or/page?p=1), for analytics.
On success the API returns a decision (allow, challenge, or block). On timeout or error, treat as allow (fail-open).
Example: minimal request (Node.js)
const API = 'https://api.trustedaccounts.org/api/v1/check-request';
const ip = req.ip || req.headers['x-forwarded-for'] || '';
const trustedId = req.cookies?.trusted_id ?? '';
const requestedPath = req.originalUrl || '/';
const checkRequestPayload = { ip, requestedPath };
if (trustedId) checkRequestPayload.trustedId = trustedId;
let checkResponse = { decision: 'allow' };
try {
const controller = new AbortController();
setTimeout(() => controller.abort(), 400);
const apiRes = await fetch(API, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer YOUR_SECRET_KEY' },
body: JSON.stringify(checkRequestPayload),
signal: controller.signal,
});
const setCookie = apiRes.headers.get('set-cookie');
if (setCookie) res.setHeader('Set-Cookie', setCookie);
checkResponse = await apiRes.json();
} catch (_) {
// Timeout or error: keep default allow
}
Handle the response (allow, challenge, block)
| Decision | Action |
|---|---|
| allow | Continue to the requested page (e.g. call next() or serve the page). |
| challenge | Redirect the user to our hosted challenge page; after completion they return to your site. |
| block | Redirect the user to our hosted blocked page. |
For challenge and block, build the redirect URL yourself and pass these query params:
trusted_id— use thetrusted_idfrom the visitor’s cookie (see Step 1; if the API sent Set-Cookie, you forwarded it so the client has the cookie).publishable_key— your publishable key.redirect_url— full URL where to send the user after challenge (e.g. back to the page they requested).
Hosted pages
| Page | URL | Params |
|---|---|---|
| Challenge | https://challenge.trustedaccounts.org/challenge.html | trusted_id, publishable_key, redirect_url |
| Blocked | https://blocked.trustedaccounts.org/blocked.html | trusted_id, publishable_key, redirect_url |
Challenge and blocked page URLs can be overridden per project in the Trusted dashboard.
Example: handling the response (Node.js)
// Your project’s publishable key; challenge and blocked pages are hosted by us
const PUBLISHABLE_KEY = process.env.PUBLISHABLE_KEY;
const CHALLENGE_URL = 'https://challenge.trustedaccounts.org/challenge.html';
const BLOCKED_URL = 'https://blocked.trustedaccounts.org/blocked.html';
// Build the full URL for our challenge or blocked page with the query params we require
function hostedPageUrl(baseUrl, trustedId, redirectUrl) {
const params = new URLSearchParams({
trusted_id: trustedId,
publishable_key: PUBLISHABLE_KEY,
redirect_url: redirectUrl,
});
return `${baseUrl}?${params.toString()}`;
}
// Use trusted_id from the cookie (you forwarded Set-Cookie in Step 1 so the client has it)
const trustedId = req.cookies?.trusted_id ?? '';
// redirect_url: after the user completes the challenge, where they go — usually the page they requested or want to visit
// Example (replace with your domain and the path the user requested, e.g. from req.originalUrl):
const redirectUrl = 'https://your-domain.com/products';
if (checkResponse.decision === 'block') {
return res.redirect(302, hostedPageUrl(BLOCKED_URL, trustedId, redirectUrl));
}
if (checkResponse.decision === 'challenge') {
return res.redirect(302, hostedPageUrl(CHALLENGE_URL, trustedId, redirectUrl));
}
// allow: no redirect, just continue to the page they requested
next();
Extra security: send headers and cookies
For stronger detection you can send headers and cookies in the same body. You must exclude sensitive data: do not send authorization, cookie (as a header), proxy-authorization, or proxy-authenticate. We strip those server-side if present. For security, do not send cookie values — only cookie names.
- headers — Optional object of header names (lowercase) to string values. Include e.g.
user-agent,referer; we may use others for current or future checks. - cookies — Optional list of cookie names only (no values). E.g.
["trusted_id"]to indicate the visitor has that cookie. Send the actualtrusted_idvalue via the top-level trustedId field.
Example: body with headers and cookies (Node.js)
const ip = req.ip || req.headers['x-forwarded-for'] || '';
const trustedId = req.cookies?.trusted_id ?? '';
const requestedPath = req.originalUrl || '/';
// Exclude sensitive headers
const SENSITIVE = new Set(['authorization', 'cookie', 'proxy-authorization', 'proxy-authenticate']);
const headers = {};
for (const [key, value] of Object.entries(req.headers)) {
if (value == null) continue;
const name = key.toLowerCase();
if (SENSITIVE.has(name)) continue;
headers[name] = Array.isArray(value) ? value.join(', ') : value;
}
const checkRequestPayload = { ip, requestedPath, headers };
if (trustedId) checkRequestPayload.trustedId = trustedId;
// Optional: send cookie names only (never send values). Derive from your request.
if (req.cookies && typeof req.cookies === 'object') {
checkRequestPayload.cookies = Object.keys(req.cookies);
} else if (req.headers?.cookie) {
const cookieHeader = Array.isArray(req.headers.cookie) ? req.headers.cookie[0] : req.headers.cookie;
checkRequestPayload.cookies = cookieHeader.split(';').map(s => s.trim().split('=')[0]).filter(Boolean);
}
const apiRes = await fetch(API, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer YOUR_SECRET_KEY' },
body: JSON.stringify(checkRequestPayload),
signal: controller.signal,
});
// cookies is always an array of names, e.g. ["trusted_id", "session_id"]; the trusted_id value is sent in trustedId.
Privacy: The trusted_id cookie is for bot protection only (no PII); include it in your cookie notice.