Open to people.
Closed to abuse.
Know what’s on the other side of every request. Give real users a clear path, and keep unwanted traffic out.
MANDATE Verify is in beta. Access is by request.
SStorefrontOverviewSearch dashboard⌘KD
Overview
Total decisions
143,660
Last 24h
Allowed
127,990
89% · 127,990 of 143,660 decisions
Challenged
7,175
Additional browser verification
Blocked
8,495
Recorded block decisions
Decisions over time
143,660decisions · Last 24h
Hourly intervals
View activity Open setup
Decision breakdown
All 143,660 decisions · 24h
Decision types
Geographic concentration
USUnited States60,33742%
DEGermany31,60522%
GBUnited Kingdom22,98616%
CACanada17,23912%
JPJapan11,4938%
How it works
Point a subdomain at MANDATE, add one script tag, and verify on your server. Start in Observe, then block when you are ready.
- Add one TXT record at _mandate on your domain to prove ownership, and one CNAME for your verify subdomain. MANDATE issues and renews its certificate.
- Load the script from your verify subdomain. The browser credential is an HttpOnly cookie on your own domain, so page JavaScript cannot read it.
- Before a protected action runs, your server asks MANDATE whether the request is verified, then applies the decision.
Using a Content Security Policy? Allow your verify subdomain for scripts and connections, along with blob workers and WebAssembly.
DNS
Add both records at your DNS provider. MANDATE issues and renews the certificate.
1Type Name Value
2TXT _mandate.yourdomain.com "YOUR_OWNERSHIP_TOKEN"
3CNAME verify.yourdomain.com YOUR_CNAME_TARGET
valueProvided by MANDATE for your site
What your dashboard confirms
Ownership
TXT found
Verify subdomain
CNAME found
Certificate
Issued
HTML
Place it in the page head. Copy takes only the highlighted line.
1<!doctype html>
2<html>
3<head>
4<script src="https://verify.yourdomain.com/g.js?k=YOUR_SITE_KEY"></script>
5</head>
6...
7</html>
valueYour public site key. Safe in the browser.
What your dashboard confirms
Domain
Verified
Browser activity
Received
Server verification
4 received
2 passed · 2 rejected
POSThttps://gate.mandate.so/validatePlain HTTPS. No SDK, CLI, or package.
1curl -X POST "https://gate.mandate.so/validate" \
2-H "Authorization: Bearer $MANDATE_API_KEY" \
3-H "Content-Type: application/json" \
4-d @- <<EOF
5{
6"high_value": true,
7"credential_mode": "cookie",
8"cookie_profile": "subdomain_v1",
9"hostname_binding_id": "YOUR_BINDING_ID",
10"credential_cookie": "$CREDENTIAL_COOKIE",
11"secret": "$MANDATE_SITE_SECRET",
12"site_key": "YOUR_SITE_KEY",
13"request_method": "POST",
14"path": "/api/login",
15"origin": "https://yourdomain.com",
16"request_proof": "$REQUEST_PROOF",
17"work_proof": "$WORK_PROOF",
18"integrity_proof": "$INTEGRITY_PROOF",
19}
20EOF
1// Before the protected action runs.
2const res = await fetch("https://gate.mandate.so/validate", {
3method: "POST",
4headers: {
5Authorization: `Bearer ${process.env.MANDATE_API_KEY}`,
6"Content-Type": "application/json",
7},
8body: JSON.stringify({
9high_value: true,
10credential_mode: "cookie",
11cookie_profile: "subdomain_v1",
12hostname_binding_id: "YOUR_BINDING_ID",
13credential_cookie: credentialCookie,
14secret: process.env.MANDATE_SITE_SECRET,
15site_key: "YOUR_SITE_KEY",
16request_method: "POST",
17path: "/api/login",
18origin: "https://yourdomain.com",
19request_proof: requestProof,
20work_proof: workProof,
21integrity_proof: integrityProof,
22}),
23});
24const decision = await res.json();
25if (res.ok && decision.success === true && decision.action === "allow") {
26// Continue with the protected action.
27}
28// Set decision.session_cookie_update_v1 as a cookie on your response.
1import json, os, urllib.request
2
3# Before the protected action runs.
4req = urllib.request.Request(
5"https://gate.mandate.so/validate",
6method="POST",
7headers={
8"Authorization": "Bearer " + os.environ["MANDATE_API_KEY"],
9"Content-Type": "application/json",
10},
11data=json.dumps({
12"high_value": True,
13"credential_mode": "cookie",
14"cookie_profile": "subdomain_v1",
15"hostname_binding_id": "YOUR_BINDING_ID",
16"credential_cookie": credential_cookie,
17"secret": os.environ["MANDATE_SITE_SECRET"],
18"site_key": "YOUR_SITE_KEY",
19"request_method": "POST",
20"path": "/api/login",
21"origin": "https://yourdomain.com",
22"request_proof": request_proof,
23"work_proof": work_proof,
24"integrity_proof": integrity_proof,
25}).encode(),
26)
27res = urllib.request.urlopen(req, timeout=5)
1// Before the protected action runs.
2body, _ := json.Marshal(map[string]any{
3"high_value": true,
4"credential_mode": "cookie",
5"cookie_profile": "subdomain_v1",
6"hostname_binding_id": "YOUR_BINDING_ID",
7"credential_cookie": credentialCookie,
8"secret": os.Getenv("MANDATE_SITE_SECRET"),
9"site_key": "YOUR_SITE_KEY",
10"request_method": "POST",
11"path": "/api/login",
12"origin": "https://yourdomain.com",
13"request_proof": requestProof,
14"work_proof": workProof,
15"integrity_proof": integrityProof,
16})
17req, _ := http.NewRequest("POST", "https://gate.mandate.so/validate", bytes.NewReader(body))
18req.Header.Set("Authorization", "Bearer "+os.Getenv("MANDATE_API_KEY"))
19req.Header.Set("Content-Type", "application/json")
20res, err := http.DefaultClient.Do(req)
1// Before the protected action runs.
2$ch = curl_init("https://gate.mandate.so/validate");
3curl_setopt_array($ch, [
4CURLOPT_POST => true,
5CURLOPT_RETURNTRANSFER => true,
6CURLOPT_HTTPHEADER => [
7"Authorization: Bearer " . getenv("MANDATE_API_KEY"),
8"Content-Type: application/json",
9],
10CURLOPT_POSTFIELDS => json_encode([
11"high_value" => true,
12"credential_mode" => "cookie",
13"cookie_profile" => "subdomain_v1",
14"hostname_binding_id" => "YOUR_BINDING_ID",
15"credential_cookie" => $credentialCookie,
16"secret" => getenv("MANDATE_SITE_SECRET"),
17"site_key" => "YOUR_SITE_KEY",
18"request_method" => "POST",
19"path" => "/api/login",
20"origin" => "https://yourdomain.com",
21"request_proof" => $requestProof,
22"work_proof" => $workProof,
23"integrity_proof" => $integrityProof,
24]),
25]);
26$res = curl_exec($ch);
valueProvided by MANDATE for your sitevalueServer-onlyvalueFrom the incoming request
What your dashboard confirms
Domain
Verified
Browser activity
Received
Server verification
4 received
2 passed · 2 rejected
Browser verification
Protection for the actions that matter.
Protect login, signup, and checkout from replay, token theft, and scripted browser abuse. Invisible verification for the actions that matter.
Your browser
Browser proof
Request + proof
Your application
Application authority
Verify proof
Decision
MANDATE
Hosted verification
Browser evidence. Application authority.Dashedcomes from the browser or is in transit
Built around your application
Integration ecosystem
Any DNS provider, any server that can make an HTTPS request. Your application keeps its own stack.
Fit protection into your stack.See the full setup
Your server, any language
Your DNS, any provider
Plain HTTPS from your server. No SDK required.
Pricing
MANDATE Verify is in beta and free while it is. Access is by request.See pricing
Build
Connect browser verification to your request flow.
Free
during public beta$19/mo after the beta
Request access Grow
Adapt protection as your traffic grows.
Free
during public beta$149/mo after the beta
Request access