Janus
API Reference

Siteverify

Server-side token validation endpoint.

Verification flow

Verification Sequence

POST /api/v1/siteverify

Validates a Janus verification token. Called from your backend after receiving the token from the client.

Request

{
  "secret": "jns_secret_live_xxxxxxxxxxxx",
  "token": "token-from-client",
  "remoteip": "1.2.3.4"  // optional
}
FieldRequiredDescription
secretYesYour site secret key
tokenYesToken received from the client SDK
remoteipNoClient IP — if provided, must match the IP used during verification

Success response

{
  "success": true,
  "challenge_ts": "2026-03-22T10:00:00.000Z",
  "hostname": "example.com",
  "action": "allow",
  "risk_score": 15
}

Error response

{
  "success": false,
  "error": "Token has expired",
  "error-codes": ["token-expired"]
}

Error codes

CodeMeaning
token-expiredToken TTL (5 minutes) exceeded
token-invalidHMAC signature verification failed
ip-mismatchremoteip doesn't match verification IP
site-mismatchToken was issued for a different site

Integration examples

Using @janus/express:

app.post('/submit', janusVerify({ secretKey, apiUrl }), handler);

Using @janus/nextjs:

const result = await verifyJanusToken(token, { secretKey, apiUrl });

Using fetch directly:

const res = await fetch(`${apiUrl}/api/v1/siteverify`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ secret: secretKey, token }),
});
const { success, action, risk_score } = await res.json();