Developer Guide
CypherGuard protects your auth & checkout flows with human-friendly risk checks. Copy the widget, emit an event, call the decision API. Thatβs it.
π Quickstart
30s setup<div id="pis-guard"
data-project="YOUR_PUBLIC_PROJECT_KEY"
data-form="#loginForm"
data-login-button="#loginBtn"
data-logo="https://cdn.pis.center/assets/gif/logo.gif"></div>
<script src="https://cdn.pis.center/v1/guard.js" defer></script>
Replace YOUR_PUBLIC_PROJECT_KEY and ensure the attributes point at your form/button.
π Authentication
Every request must include your X-Project-Key header. Use the public key in browser (widget), secret key on server.
X-Project-Key: YOUR_PUBLIC_OR_SECRET_KEY
Content-Type: application/json
π‘ POST /guard/event
Client β ServerSend when a user initiates an action (e.g., login started, signup started). Payload includes lightweight device/behavior signals.
typedevice.uapageselfie_status
curl -X POST "$API_BASE/guard/event" \
-H "Content-Type: application/json" \
-H "X-Project-Key: $PROJECT_KEY" \
-d '{
"type": "login_attempt_started",
"device": { "ua": "Mozilla/5.0 ..." },
"selfie_status": "skipped",
"page": "https://example.com/login"
}'
fetch("$API_BASE/guard/event", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Project-Key": "$PROJECT_KEY"
},
body: JSON.stringify({
type: "login_attempt_started",
device: { ua: navigator.userAgent },
selfie_status: "skipped",
page: location.href
})
})
{
"type": "login_attempt_started",
"device": { "ua": "string" },
"selfie_status": "skipped|required|passed|failed",
"page": "https://.../login"
}
π POST /guard/attempt
ServerLog an auth attempt with minimal user context. Use this to correlate an event with your user record.
fetch("$API_BASE/guard/attempt", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Project-Key": "$PROJECT_KEY",
"X-Widget-Version": "1.0.0"
},
body: JSON.stringify({
ok: true,
user: { id: "u_1", email: "a@b.com" },
page: "https://example.com/login"
})
})
π§ POST /guard/decision
ServerAsk CypherGuard how to proceed. Youβll get an action: allow, challenge, or deny, a score, and reasons.
fetch("$API_BASE/guard/decision", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Project-Key": "$PROJECT_KEY"
},
body: JSON.stringify({
event_id: "evt_123",
user: { id: "u_1", email: "a@b.com" },
page: "https://example.com/login"
})
}).then(r => r.json())
Sample response
{
"ok": true,
"action": "allow", // or "challenge", "deny"
"score": 0.21,
"reasons": ["new_device","vpn_detected"]
}
π Webhooks
Server β YouReceive asynchronous risk updates or challenge outcomes. Configure your endpoint in the dashboard.
POST https://yourapp.com/webhooks/cypherguard
{
"type": "decision.created",
"data": {
"event_id": "evt_123",
"action": "challenge",
"score": 0.62,
"reasons": ["velocity_spike","disposable_email"]
},
"created_at": "2025-09-26T12:00:00Z"
}
π§ͺ Test it live
Desktop only
This feature cannot be displayed on mobile. Please open this page on a desktop to try the live sandbox.