human, bot, or inconclusive) and a risk score (integer 0 – 100). Your backend uses these to decide what to do.
Verdicts
Risk score
The risk score is an integer from0 (definitely human) to 100 (definitely bot). It’s normalized via a sigmoid function, so scores cluster near the extremes - most sessions score below 10 or above 90.
Use the score for granular policy when the verdict alone isn’t enough:
Evaluation phases
Foil evaluates sessions in two phases:If you call
getSession() before the user interacts with the page, you’ll get a snapshot-phase result. For highest confidence, wait for at least a few seconds of user interaction.Preliminary vs final
Snapshot-phase results are usually
preliminary. Behavioral-phase results are final.
Automation attribution
When Foil identifies the specific automation tool, the session includes attribution details:
Attribution includes the framework name, variant, organization (if known), and a confidence score.
Using verdicts in your API
The sealed token returns theDecision shape directly:
GET /v1/sessions/:id) renames these fields into a more descriptive, action-oriented vocabulary. (The list endpoint, GET /v1/sessions, keeps the sealed-token names - verdict, phase, is_provisional - in its latest_decision summary.)
The underlying data is identical - only the field names and the
automation_status / decision_status value labels differ.
Policy recommendations
- Start with report-only - log verdicts without blocking for the first week
- Treat
inconclusiveas an opportunity - challenge with CAPTCHA or email verification, don’t block - Wait for behavioral phase on high-value actions when possible
- Use the score for edge cases - a
botverdict at71is weaker than one at98 - Keep your Foil decision in your audit trail - log the sessionId alongside the business action
What’s next
- Detection categories - what signals feed into the score
- Server verification - verify handoffs on your backend
- Sessions API - full session detail response