Signalcache API
Score a transaction for fraud in a single request — features fetched, computed, and scored in-memory, server-side p99 under 10ms.
Quickstart
Send a transaction, get back a decision. Here it is in three flavors.
cURL
curl -X POST https://api.signalcache.cloud/v1/score \
-H "x-api-key: $SIGNALCACHE_API_KEY" \
-H "content-type: application/json" \
-d '{
"entity": { "card": "card_9f2a", "device": "dev_abc", "ip": "203.0.113.7", "bin": "411111" },
"amount": 248.00
}'
Python
from signalcache import Client
sc = Client("sk_live_...")
d = sc.score(card="card_9f2a", device="dev_abc",
ip="203.0.113.7", bin="411111", amount=248.00)
if d.is_declined:
block(d.reason_codes)
Node (fetch)
const r = await fetch("https://api.signalcache.cloud/v1/score", {
method: "POST",
headers: { "x-api-key": key, "content-type": "application/json" },
body: JSON.stringify({ entity: { card, device, ip, bin }, amount }),
});
const d = await r.json(); // { action, score, reason_codes, ... }
Authentication
Every request (except /health) needs your API key, sent either way:
x-api-key: <key>Authorization: Bearer <key>
A missing or unknown key returns 401. Keys are scoped to your tenant — your feature state is fully isolated from every other tenant.
Base URL
Managed cloud:
https://api.signalcache.cloud
Self-hosting in your VPC (Enterprise)? Point any client at your own host — the API is identical.
POST/v1/score
Read the entity's point-in-time features, score them, and record the event for future velocity — all in one call.
Request body
| field | type | notes |
|---|---|---|
entity.card | string | required — your card/account token (not a PAN) |
entity.device | string | optional device id |
entity.ip | string | optional IP address |
entity.bin | string | optional card BIN (first 6) |
amount | number | transaction amount |
declined | bool | optional — mark this event as a decline (feeds decline velocity) |
Response 200
{
"event_id": "evt_00000000002a",
"action": "decline", // accept | review | decline
"score": 0.94, // 0.0 – 1.0
"reason_codes": ["velocity_spike", "new_device"],
"features": { ... }, // the point-in-time features used
"latency_ms": 0.08, // server-side scoring time
"tenant": "acme"
}
Thresholds: score ≥ 0.80 → decline, ≥ 0.55 → review, else accept.
POST/v1/ingest
Same body as /v1/score, but only updates the feature store — no scoring, no decision returned. Use it to backfill history or record events you don't need scored. Returns { "ok": true }.
GET/v1/features
Read the current feature vector for an entity without scoring.
GET /v1/features?card=card_9f2a&ip=203.0.113.7&bin=411111
Returns the same features object described in the glossary.
GET/v1/stats
Operational stats for your tenant: entities tracked, decisions served, and server-side latency percentiles.
{ "cards_tracked": 12840, "decisions": 91233,
"latency_ms": { "p50": 0.02, "p95": 0.07, "p99": 0.22 } }
GET/health
Unauthenticated liveness check. Returns { "ok": true }.
Feature glossary
The features Signalcache computes on the hot path and returns in every decision:
| feature | what it measures |
|---|---|
card_txn_velocity_60s | transactions from this card in the last 60 seconds |
card_txn_velocity_5m | transactions in the last 5 minutes |
card_txn_velocity_1h | transactions in the last hour |
card_amount_sum_5m | total amount charged to this card in 5 minutes |
card_amount_zscore | how anomalous this amount is vs the card's history |
card_distinct_devices_24h | distinct devices seen for this card in 24h |
card_declines_5m | declines for this card in the last 5 minutes |
ip_distinct_cards_24h | distinct cards seen from this IP in 24h (fan-out) |
bin_velocity_est | recent global velocity for this BIN — catches distributed BIN attacks |
Reason codes
Human-readable explanations attached to a decision (auditable, dispute-ready):
| code | meaning |
|---|---|
velocity_spike | unusually high transaction rate for this card |
new_device | more distinct devices than expected |
amount_anomaly | amount far outside the card's normal range |
prior_declines | recent declines on this card |
ip_card_fanout | many cards from one IP |
bin_attack_pattern | BIN-testing pattern across many cards |
Errors & limits
| status | meaning |
|---|---|
400 | malformed request (e.g. missing entity.card) |
401 | missing or invalid API key |
429 | rate limit exceeded — back off and retry |
5xx | server error — safe to retry with backoff |
Errors return { "error": "..." }. Rate limits depend on your plan; contact us if you need a higher ceiling for load testing.
SDKs
Python
pip install signalcache
See the Python SDK README for the full reference. Other languages: call the JSON API directly (examples above) — more SDKs coming.