Assess an event
Assesses a sign-up, login or other event in the API key's environment and returns a decision (allow, review or block) with a score and the reasons behind it. COSS combines email and IP signals with what it has seen in this environment (velocity, accounts sharing a mailbox, identifiers you reported) and your allow and block lists. Signals that are unavailable at the moment are skipped and listed in degraded. Call it from your server, never from the browser, and treat errors as allow (fail open) so an outage never locks your users out. review decisions also fire a risk.assessment.review webhook. Sandbox (coss_test_…) keys accept documented test addresses (192.0.2.x, @disposable.test, @undeliverable.test).
bearerAuthAuthorizationBearer <token>A secret API key from the dashboard: coss_live_… for production environments, coss_test_… for sandbox environments.
Idempotency-Key?stringMakes retries safe: a repeated request with the same key and body returns the original assessment instead of assessing (and counting) the event again, for 24 hours. 1-256 characters.
1 <= length <= 256Coss-Version?"2026-10-10"The API version (a date) to use for this request. Defaults to your organization's version, pinned to the latest one when it first used the API and upgraded from the dashboard. The SDK always sends the version it was built for.
"2026-10-10"application/json- body
- body
- …
event*RiskEventWhat is being assessed. custom events are named by event_name; velocity is counted per event.
"signup""login""message""checkout""custom"event_name?stringRequired for custom events (e.g. invite_sent), not allowed otherwise.
^[a-z0-9][a-z0-9._-]{0,63}$user?ip?|The client's IP address (not your server's or proxy's).
user_agent?stringThe client's user agent.
length <= 1024The assessment. A replay returns the original assessment.
application/json- response
- response
- …
object*"risk_assessment""risk_assessment"id*stringevent*RiskEventWhat is being assessed. custom events are named by event_name; velocity is counted per event.
"signup""login""message""checkout""custom"event_name*string|nulldecision*RiskDecisionallow: go ahead. review: suspicious; let it through with limits, or hold it for a person. block: refuse it.
"allow""review""block"score*number0-1: how risky the signals are together. Lists can decide regardless of the score.
0 <= value <= 1reasons*array<>Why, most significant first.
signals*user*ip*|null once removed (90 days after).
degraded*array<>Signal groups that were unavailable for this assessment (it was made without them).
outcome*|The latest outcome you reported with feedback.
review_status*|open for review decisions until you send feedback, then resolved.
created_at*stringdate-timeimport { Coss } from "coss";const coss = new Coss({ apiKey: process.env.COSS_API_KEY, baseUrl: "https://api.coss.com",});const { data, error } = await coss.risk.assess({ event: "signup", user: { email: "ada@gmail.con", }, ip: "203.0.113.7", user_agent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 15_0) AppleWebKit/605.1.15",});{ "object": "risk_assessment", "id": "rsk_01k7c8m4q2f3e9v6t5r1n0p8yz", "event": "signup", "event_name": null, "decision": "review", "score": 0.62, "reasons": [ { "code": "email.typo", "message": "The domain looks like a typo of gmail.com.", "suggestion": "gmail.com" }, { "code": "velocity.signups_per_ip_1h", "message": "7 sign-ups from this IP address in the last hour.", "value": 7, "threshold": 5, "window": "1h" } ], "signals": { "email": { "domain": "gmail.con", "valid": true, "disposable": false, "deliverability": "deliverable", "role_account": false, "free_provider": false, "suggestion": "gmail.com" }, "ip": { "version": 4, "private": false, "tor": false, "hosting": false, "hosting_provider": null, "hosting_kind": null, "asn": 64500, "as_name": "Example Broadband", "country": "GB" }, "velocity": { "ip_1h": 7, "ip_24h": 9, "subnet_1h": 7, "mailbox_24h": 1 } }, "user": { "id": null, "email": "ada@gmail.con" }, "ip": "203.0.113.7", "degraded": [], "outcome": null, "review_status": "open", "created_at": "2026-01-15T09:30:00.000Z"}