Skip to main content

Server-side Integration

New here? Start with the Quick Start Guide — it walks you through observe-mode integration first (always serve the page, decisions in your dashboard). Return here when you are ready to enforce challenge/block redirects or deploy at the edge.

Call the check-request API from your server to get allow, block, or challenge for each request. Start in observe mode (Step 1): always serve the page while decisions appear in your dashboard. When you are ready, activate active protection (Step 2): redirect visitors to challenges or block bots. To use the API at the edge (e.g. Cloudflare Workers), see CDN integration.


Step 1: Integrate in observe mode

Call the API on every page request and always continue serving the page — even when the API returns challenge or block. Decisions show in your dashboard so you can tune rules before enforcing redirects.

Call POST /api/v1/check-request with your secret in the Authorization header and a JSON body with:

  • ip — client IP from the incoming request (e.g. from x-forwarded-for or your connection).
  • requestedPath — path the visitor requested (e.g. / or /page?p=1), for analytics and routing context.
  • trustedId — session/visitor ID from the trusted_id cookie when present (send an empty string on the first visit; forward Set-Cookie from the API so the browser gets the cookie).
  • headers (optional) — request headers for stronger detection. Exclude sensitive values such as authorization, cookie, proxy-authorization, and proxy-authenticate.
  • cookies (optional) — cookie names only (never values), e.g. ["trusted_id"]. Send the trusted_id value via trustedId.

On success the API returns a decision (allow, challenge, or block). On timeout or error, treat as allow (fail-open).

Example: observe-mode integration (Node.js)

// Call on every page request from your server
const API = 'https://api.atmosvere.eu/api/v1/check-request';
// Visitor IP from the incoming request (use your framework/proxy headers)
const ip = req.ip || req.headers['x-forwarded-for'] || '';
// Path the visitor requested (e.g. /pricing?ref=ads)
const requestedPath = req.originalUrl || '/';
// Session/visitor ID from the trusted_id cookie (empty on first visit until the API sets the cookie)
const trustedId = req.cookies?.trusted_id ?? '';
// (optional) Request headers for stronger detection — exclude authorization, cookie, etc.
const headers = {
'user-agent': req.headers['user-agent'] ?? '',
referer: req.headers.referer ?? '',
};
// (optional) Cookie names only, never values (e.g. ['trusted_id'])
const cookies = req.cookies ? Object.keys(req.cookies) : [];

// Send these fields to Atmosvere in the POST body
const payload = { ip, requestedPath, trustedId };
// (optional) include headers and cookies when available
if (Object.keys(headers).length) payload.headers = headers;
if (cookies.length) payload.cookies = cookies;

// Default to allow if the API is slow or unreachable (fail-open)
let checkResponse = { decision: 'allow' };
try {
// Fail-safe timeout: abort slow API calls so you still serve the page (fail-open)
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(payload),
signal: controller.signal,
});

// Forward Set-Cookie so the visitor receives trusted_id from the API
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 (fail-open)
}

// OBSERVE MODE (default): always continue — decisions show in your dashboard
next();

// Redirect logic for block/challenge starts in Step 2 below

Step 2: Activate active protection

When you are ready to enforce decisions, handle challenge and block by redirecting visitors to our hosted pages instead of only observing in your dashboard. allow still means continue to the requested page.

DecisionAction
allowContinue to the requested page (e.g. call next() or serve the page).
challengeRedirect the user to our hosted challenge page; after completion they return to your site.
blockRedirect the user to our hosted blocked page.

For challenge and block, build the redirect URL yourself and pass these query params:

  • trusted_id — use the trusted_id from 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

PageURLParams
Challengehttps://pages.atmosvere.eu/challenge.htmltrusted_id, publishable_key, redirect_url
Blockedhttps://pages.atmosvere.eu/blocked.htmltrusted_id, publishable_key, redirect_url

Challenge and blocked page URLs can be overridden per project in the Trusted dashboard.

Example: challenge and block redirects (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://pages.atmosvere.eu/challenge.html';
const BLOCKED_URL = 'https://pages.atmosvere.eu/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();

Optional next step: Frontend Integration — Add the browser SDK for stronger detection signals in the visitor’s browser.

Privacy: The trusted_id cookie is for bot protection only (no PII); include it in your cookie notice.