A BEHAVIORAL FRAUD LAYER FOR THE CRYPTO ON-RAMP
API REFERENCE

One endpoint. Send the signal vector, get a verdict.

No SDK required — a plain HTTPS POST with a JSON body. Pay per call against an API key, or machine-to-machine over x402.

PRIVATE BETA

api.straja.app is not open to public sign-up. Keys are issued with a pilot, and the reference below is the contract you'll integrate against — complete and stable, but live only for pilot partners today. Request access.

AUTHENTICATION

Two ways in.

API key

Standard bearer token, issued per account. Billed monthly against your plan.

Authorization: Bearer sk_live_••••••••
Content-Type: application/json

x402 — pay per call

No account, no key. An agent gets a 402, pays, and retries. Built for machine buyers that can't hold a contract.

402 Payment Required
X-Payment-Price: $0.10
ENDPOINT

POST /v1/verdict

Send whatever slice of the signal vector you have. Missing fields are treated as unknown, not as zero — a signal you can't measure never counts against a user.

# One call, one verdict
curl https://api.straja.app/v1/verdict \
  -H "Authorization: Bearer sk_live_••••••••" \
  -H "Content-Type: application/json" \
  -d '{
    "amount_eur": 4800,
    "signals": {
      "idle_gaps_over_60s": 4,
      "tab_switches": 3,
      "address_entry_method": "pasted",
      "deposit_escalation": [200, 1000, 4800]
    }
  }'

Response

tier
"PASS" · "SOFT" · "INTERVENE"
string
reasoning
Plain-language explanation of which signals drove the decision.
string
key_signals
The short phrases naming what actually moved the tier, e.g. 'idle_gaps + pasted address'.
string[]
decision_id
Unique ID for audit lookup and probe follow-up calls.
string
probe_required
True only on INTERVENE — signals the client to launch the probe flow.
boolean
TRY IT

Playground

Pick a scenario and see the shape of a response. This returns a stored example — it isn't a live call to the model.

stored example — not a live call200 OK
// This playground returns a stored example.
// The live API runs the same engine on real signals.

{
  "tier": "INTERVENE",
  "reasoning": "Coached-session pattern: repeated idle gaps, pasted address, escalating deposits, destination created 2 days ago.",
  "decision_id": "d_8f21c0ab",
  "probe_required": true,
  "signals": {
    "idle_gaps_over_60s": 4,
    "tab_switches": 3,
    "address_entry_method": "pasted",
    "deposit_escalation": [200, 1000, 4800]
  }
}