Skip to main content
Every /trace call is anchored to an event: a specific user action your system wants to evaluate. Policies are scoped to event types, so the rules you write for a login are separate from the rules you write for a signup, each with the signals and thresholds that make sense for that action.

Event types

Each event type gets its own policy under Guard. A policy for signup can deny disposable emails and automation; a policy for login can deny credential stuffing based on per-IP failure velocity (rules that would be irrelevant on the other type).

Status

Every event has a status: attempted, succeeded, or failed.

How status is determined

Status reaches tracenow in two ways depending on where the trace originates. At the Cloudflare edge (outcome trace) The Worker fires an initial trace with status: attempted before the request reaches your origin. Once your origin responds, the Worker maps the HTTP response code to an outcome and fires a second, non-blocking trace:
  • 2xxsucceeded
  • 4xx / 5xxfailed
You configure this mapping per route when you set up the integration. The second trace is async, so it adds zero latency to the user-facing response. In the in-app call When you call /trace from your backend, you set status directly to the real outcome you observed. This is always more accurate than the HTTP-code mapping because your server knows exactly what happened: a 200 login response could still mean a wrong-password rejection depending on your API design.
The in-app call lets you pass status: "failed" even if your server returns 200. Use it whenever your response shape doesn’t map cleanly to HTTP codes.

Why status matters

Status is a first-class signal. You can write rules against event.status directly, which unlocks the most powerful account-takeover patterns:
  • Credential stuffing: velocity.ip.failed_count_1h gt 5 AND event.status eq "failed". Blocks an IP racking up login failures.
  • Suspicious success after failures: velocity.user.failed_count_1h gt 3 AND event.status eq "succeeded". Challenges a login that succeeds after a brute-force run.
  • New country on success: ip.is_new_country_for_user AND event.status eq "succeeded". Challenges a login from a country the account has never used.
Without status, none of these conditions are expressible. Without the in-app call, the outcome comes from HTTP code mapping. That is close enough for most apps, but the in-app call gives you exact control when you need it.

Event × status reference

What goes into an event

Beyond the type and status, a trace carries the signals tracenow enriches and evaluates:
Send whatever you have. Not all fields are required. subject_user_id is only available from the in-app call; the edge never has it. See Server-side integration for the full field reference.

Next steps

Signals

Every field your rules can evaluate: IP, email, phone, device, velocity, and event status.

Rules

How to combine signals into conditions, and conditions into policies.