POST /v1/score
Score a signup. Requires Bearer authentication. Returns a verdict in under 500ms (P95).
Request
POST https://api.veritus.uk/v1/score
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"form_id": "abc12345-...-...", // optional, use form's UUID
"signup": {
"name": "Sarah Johnson",
"email": "sarah@example.com",
"phone": "+447700900111",
"country": "GB",
"address_line": "10 Downing Street",
"postcode": "SW1A 2AA",
"ip": "86.142.71.21", // server-side: pass the real IP, not request.remote_addr if behind a proxy
"user_agent": "Mozilla/5.0 ...", // optional
"password": "secret123" // optional; used for HIBP check; never stored
}
}
All fields are optional except either email or phone
Veritus scores whatever you give it. The more you pass, the more accurate the verdict. Minimum useful input: email + IP.
Response (200 OK)
{
"id": "8ce48bb4-0381-4e4f-959a-9e44ba0aa61f",
"score": 5,
"verdict": "allow",
"reasons": [],
"duration_ms": 245,
"mode": "live",
"model_version": "rules_v1"
}
Example with reasons
{
"id": "59b095c8-e521-41d2-bb1d-cb46544c9ae0",
"score": 35,
"verdict": "review",
"reasons": [
{
"code": "IP_DATACENTRE",
"weight": 20,
"detail": "Signup originated from a datacentre IP (Google LLC)",
"severity": "medium"
},
{
"code": "IP_COUNTRY_MISMATCH",
"weight": 15,
"detail": "IP geo-location (US) does not match declared country (GB)",
"severity": "medium"
}
],
"duration_ms": 26,
"mode": "live",
"model_version": "rules_v1"
}
Field reference
| id | UUID for this check. Use in support tickets, look up at /dashboard/check/<id> |
| score | 0-100. Sum of triggered reason weights, capped at 100. |
| verdict | 'allow', 'review', or 'block' |
| reasons | Array of {code, weight, detail, severity}. See scoring model for codes. |
| duration_ms | Total request latency on our side. Network RTT not included. |
| mode | 'live' or 'test' based on API key used |
| model_version | Tracks scorer version for audit/regression analysis |
Found a typo or have a suggestion?
Let us know.