Forms are the front door; APIs are every other door#
Once your web app moves logic into fetch calls (search, autocomplete, pricing lookups, content feeds), those endpoints become the cheapest way to abuse your service. A scraper doesn’t render your page or fill in your form; it calls /api/search ten thousand times.
Rate limiting helps but is blunt: attackers rotate IPs, and your heaviest legitimate users look exactly like abusers by request count alone. What’s missing is the question Shield answers on forms, is a human driving this?, attached to each request.
1. Attach a Shield token to API calls#
The widget’s JavaScript API can produce tokens on demand as well as on form submit. Request one and send it in a header your server checks:
// Render an invisible widget once: it verifies in the background
// and keeps its token fresh automatically
const widgetId = edgeShield.render(document.getElementById('shield'), {
sitekey: 'es_your_sitekey',
mode: 'invisible',
})
// Attach the current token to each protected request
await fetch('/api/search', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Edge-Shield-Token': edgeShield.getResponse(widgetId),
},
body: JSON.stringify({ query }),
})The verification runs invisibly in a background thread, so your users never see anything. See the JS API docs for the full programmatic interface.
2. Pick the right verification path#
For forms, one call to siteverify per submission is nothing. For an API taking hundreds of requests a second, a network round trip per request is real latency. Shield gives you a second option: tokens are Ed25519-signed JWTs, and the public key is published at a standard JWKS endpoint. Your server can verify them locally, with zero network calls.
import { createRemoteJWKSet, jwtVerify } from 'jose'
const JWKS = createRemoteJWKSet(
new URL('https://shield.edge.network/.well-known/jwks.json')
)
// Zero network calls per request: the key set is cached
async function verifyOffline(token) {
const { payload } = await jwtVerify(token, JWKS, {
issuer: 'edge-shield',
subject: process.env.SHIELD_SITEKEY, // REQUIRED: binds tokens to YOUR widget
})
// Narrow the replay window: reject tokens older than 60s
if (Date.now() / 1000 - payload.iat > 60) throw new Error('stale token')
return payload.score // 1–100
}The trade-off: offline verification cannot enforce single-use. The ledger of spent tokens lives on Shield’s servers, so a token verified offline stays valid for its full five-minute lifetime, however many times it’s presented. The iat age check above narrows that window, but the rule of thumb is:
- Offline: for high-throughput, lower-stakes endpoints (search, previews, read APIs) where latency matters more than strict single-use.
siteverify: for anything a replayed token shouldn’t touch, such as signups, payments and mutations. It’s the only path with a strict single-use guarantee.
Full details, including key rotation behaviour, are in the offline verification docs.
3. Don’t lock out the automation you want#
Some clients hitting your API without a widget token are exactly who you want: AI agents shopping or researching on behalf of real customers. Agents that sign their requests with Web Bot Auth can be identified without any widget at all. Forward the signature headers to agentverify:
// A signed agent request hit your API directly, with no widget involved.
// Forward its signature headers and Shield verifies the identity.
const res = await fetch('https://shield.edge.network/agentverify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
secret: process.env.SHIELD_SECRET,
authority: req.headers.host,
headers: {
'signature-agent': req.headers['signature-agent'],
'signature-input': req.headers['signature-input'],
'signature': req.headers['signature'],
},
}),
})
const { success, agent } = await res.json()
if (success && agent.verified) allowFor(agent.domain)So the full policy for an API endpoint becomes:
- Valid Shield token with a decent score → human, allow.
- Valid Web Bot Auth signature → known agent, allow (with its own rate tier if you like).
- Neither → the automation that refused to identify itself, which is the traffic you wanted to stop.
Verified AI agents with Web Bot Auth covers this in depth.
Keep learning
Security3 min read
Bot protection with Edge Shield
Stop form spam, credential stuffing and fake signups without ever showing a human a puzzle. Two lines on the page, one HTTP call on the server. Free forever.
Security4 min read
Verified AI agents with Web Bot Auth
The bot problem changed. Some automation is your customers' AI agents trying to buy from you. Security now means telling declared automation apart from anonymous automation and treating each accordingly.
Security4 min read
Securing login & signup flows
Credential stuffing and fake account waves are the two most common attacks on any site with a login form. Here's how to stop both without adding friction for the humans you actually want.