SKOOR Risk Money movement. Skoored by AI.

Pre-flight

Score a proposed transfer before origination.

The same features, scorer and bands as a landed transfer, answered inside the bank's decision window and recorded so it can be graded against the outcome once the transfer lands and is matched back (same program, counterparty and amount within 24 hours). degraded is true when a source the answer leans on is missing or stale, so a thin answer is never mistaken for a confident one.

Preflight

FieldTypeNotes
preflightIdstring (uuid)
decision"clear" | "review" | "hold"hold = hold band, hard signal or hard limit hit; review = review band, unscored or any soft limit hit; clear otherwise.
skoorinteger | null
band"clear" | "review" | "hold" | "unscored"
versionstring
ninteger
confidencenumber | null
reasonsReason[]
limitsHitLimitHit[]
degradedbooleanTrue when a feature source the answer leans on is missing or stale.
degradedReasonsstring[]Why it is degraded (empty on a replayed answer).
latencyMsinteger
idempotentbooleanTrue when the answer was replayed from the idempotency key.
programIdstring (uuid)

PreflightRequest

FieldTypeNotes
programId (optional)string (uuid)One of programId or programSlug is required.
programSlug (optional)string
idempotencyKey (optional)stringSame key on the same tenant returns the same answer (200 instead of 201).
transferobject
transfer.rail"ach" | "wire" | "realtime" | "book" | "intl_wire" | "check" | "card"
transfer.direction"outgoing" | "incoming"
transfer.type (optional)"CREDIT" | "DEBIT" | null
transfer.amountCentsstringInteger cents as a string.
transfer.currency (optional)stringDefault USD.
transfer.entityId (optional)string
transfer.counterpartyId (optional)string
transfer.counterparty (optional)objectDescribe a counterparty not on file; matched by routing + last4, else by name, else scored as a first-time stranger.
transfer.counterparty.namestring
transfer.counterparty.routingNumber (optional)string
transfer.counterparty.accountLast4 (optional)string
transfer.counterparty.countryCode (optional)string
transfer.effectiveOn (optional)string
transfer.description (optional)string

PreflightDetail

FieldTypeNotes
preflightIdstring (uuid)
decision"clear" | "review" | "hold"
skoorinteger | null
band"clear" | "review" | "hold" | "unscored"
versionstring
ninteger
confidencenumber | null
reasonsReason[]
limitsHitLimitHit[]
degradedboolean
degradedReasonsstring[]
latencyMsinteger
idempotentboolean
programIdstring (uuid)
requestobjectThe request as submitted plus operator and resolved {entityId, counterpartyId, counterpartyCountry}.
matchedTransferIdstring | nullSet when the transfer later landed and was matched back (same program, counterparty, amount, within 24h).
createdAtstring (date-time)

PreflightStats

FieldTypeNotes
windowDaysinteger
countinteger
byDecisionobject
byDecision.clearinteger
byDecision.reviewinteger
byDecision.holdinteger
latencyMsobject
latencyMs.p50number | null
latencyMs.p90number | null
latencyMs.ninteger
matchedobjectShare of pre-flights matched to a landed transfer.
matched.valuenumber | nullnull when nothing was measured
matched.nintegerobservations behind the value
degradedobjectShare of degraded answers.
degraded.valuenumber | nullnull when nothing was measured
degraded.nintegerobservations behind the value
gradedobjectMatched pre-flights whose transfer later received a bad/ok label.
graded.ninteger
graded.holdAndBadinteger
graded.holdAndOkinteger
graded.notHoldAndBadinteger
graded.notHoldAndOkinteger
graded.holdPrecisionnumber | null
graded.holdRecallnumber | null

LimitHit

FieldTypeNotes
limitstring<actor>.<kind>: entity|counterparty × per_transaction|daily|monthly.
actor"counterparty" | "entity"
actorIdstring
band"clear" | "review" | "hold" | "unscored"
capstringThe cap at that band. Integer cents as a string (bigint-safe).
observedstringAlready moved in the window (0 for per_transaction). Integer cents as a string (bigint-safe).
proposedstringThis amount. Integer cents as a string (bigint-safe).
severity"hard" | "soft"

Endpoints

post/api/preflight

Score a proposed transfer

Answers clear / review / hold for a transfer that has not been originated yet, and records the answer. 201 on a new answer; 200 when idempotencyKey replays a stored one (then idempotent: true and degradedReasons is empty). Body limit 64 KB.

AuthBearer + X-Operator
OperationPre-flight · POST /api/preflight

Parameters

NameInTypeNotes
tenant (optional)querystringTenant slug. Optional: the bearer token already proves the tenant. Pass it to be explicit.
Idempotency-Key (optional)headerstring1–255 characters. A replay with the same body returns the stored status and body with Idempotent-Replayed: true; a different body under the same key is 409.

Request body (application/json, required) · PreflightRequest

FieldTypeNotes
programId (optional)string (uuid)One of programId or programSlug is required.
programSlug (optional)string
idempotencyKey (optional)stringSame key on the same tenant returns the same answer (200 instead of 201).
transferobject
transfer.rail"ach" | "wire" | "realtime" | "book" | "intl_wire" | "check" | "card"
transfer.direction"outgoing" | "incoming"
transfer.type (optional)"CREDIT" | "DEBIT" | null
transfer.amountCentsstringInteger cents as a string.
transfer.currency (optional)stringDefault USD.
transfer.entityId (optional)string
transfer.counterpartyId (optional)string
transfer.counterparty (optional)objectDescribe a counterparty not on file; matched by routing + last4, else by name, else scored as a first-time stranger.
transfer.counterparty.namestring
transfer.counterparty.routingNumber (optional)string
transfer.counterparty.accountLast4 (optional)string
transfer.counterparty.countryCode (optional)string
transfer.effectiveOn (optional)string
transfer.description (optional)string

Responses

200 — Replayed from the idempotency key. Preflight

FieldTypeNotes
preflightIdstring (uuid)
decision"clear" | "review" | "hold"hold = hold band, hard signal or hard limit hit; review = review band, unscored or any soft limit hit; clear otherwise.
skoorinteger | null
band"clear" | "review" | "hold" | "unscored"
versionstring
ninteger
confidencenumber | null
reasonsReason[]
limitsHitLimitHit[]
degradedbooleanTrue when a feature source the answer leans on is missing or stale.
degradedReasonsstring[]Why it is degraded (empty on a replayed answer).
latencyMsinteger
idempotentbooleanTrue when the answer was replayed from the idempotency key.
programIdstring (uuid)

201 — Scored and recorded. Preflight

FieldTypeNotes
preflightIdstring (uuid)
decision"clear" | "review" | "hold"hold = hold band, hard signal or hard limit hit; review = review band, unscored or any soft limit hit; clear otherwise.
skoorinteger | null
band"clear" | "review" | "hold" | "unscored"
versionstring
ninteger
confidencenumber | null
reasonsReason[]
limitsHitLimitHit[]
degradedbooleanTrue when a feature source the answer leans on is missing or stale.
degradedReasonsstring[]Why it is degraded (empty on a replayed answer).
latencyMsinteger
idempotentbooleanTrue when the answer was replayed from the idempotency key.
programIdstring (uuid)

400 — Validation failed; error lists the paths. Error

FieldTypeNotes
errorstringWhat went wrong, in one sentence.
requestId (optional)stringPresent once the gateway is live: the X-Request-Id of the failed request.

401 — Bearer token missing or unknown. Error

FieldTypeNotes
errorstringWhat went wrong, in one sentence.
requestId (optional)stringPresent once the gateway is live: the X-Request-Id of the failed request.

404 — Unknown program on this tenant. Error

FieldTypeNotes
errorstringWhat went wrong, in one sentence.
requestId (optional)stringPresent once the gateway is live: the X-Request-Id of the failed request.

Example

curl -s -X POST "https://skoor.ai/risk/api/preflight?tenant=demo" \
  -H "Authorization: Bearer test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "X-Operator: you@bank.example" \
  -H "Content-Type: application/json" \
  -d '{"programSlug":"northwind-payroll","idempotencyKey":"pf-2026-09-17-0001","transfer":{"rail":"ach","direction":"outgoing","type":"CREDIT","amountCents":"185000","currency":"USD","entityId":"enti_sim_acme","counterparty":{"name":"Blue Ridge Landscaping","routingNumber":"021000021","accountLast4":"4421","countryCode":"US"},"description":"Payroll 2026-09-19"}}'

Response

{
  "preflightId": "5f3c1c8e-2a44-4c0b-9d0f-2b0a2f6e7c11",
  "decision": "clear",
  "skoor": 12,
  "band": "clear",
  "version": "trs-v1",
  "n": 210,
  "confidence": 0.81,
  "reasons": [
    {
      "id": "TRS-CP-01",
      "signal": "counterparty.first_time",
      "weight": 8,
      "hard": false,
      "sentence": "This is the first transfer with this counterparty."
    }
  ],
  "limitsHit": [],
  "degraded": false,
  "degradedReasons": [],
  "latencyMs": 41,
  "idempotent": false,
  "programId": "a1e0c2d4-6b7f-4d8e-9a3b-0c1d2e3f4a55"
}

get/api/preflight/stats

Pre-flight statistics for a window

AuthBearer + X-Operator
OperationPre-flight · GET /api/preflight/stats

Parameters

NameInTypeNotes
tenant (optional)querystringTenant slug. Optional: the bearer token already proves the tenant. Pass it to be explicit.
days (optional)queryintegerWindow in days, 1–365 (default 30).

Responses

200 — Counts by decision, latency percentiles, matched and degraded shares, and the graded confusion counts. PreflightStats

FieldTypeNotes
windowDaysinteger
countinteger
byDecisionobject
byDecision.clearinteger
byDecision.reviewinteger
byDecision.holdinteger
latencyMsobject
latencyMs.p50number | null
latencyMs.p90number | null
latencyMs.ninteger
matchedobjectShare of pre-flights matched to a landed transfer.
matched.valuenumber | nullnull when nothing was measured
matched.nintegerobservations behind the value
degradedobjectShare of degraded answers.
degraded.valuenumber | nullnull when nothing was measured
degraded.nintegerobservations behind the value
gradedobjectMatched pre-flights whose transfer later received a bad/ok label.
graded.ninteger
graded.holdAndBadinteger
graded.holdAndOkinteger
graded.notHoldAndBadinteger
graded.notHoldAndOkinteger
graded.holdPrecisionnumber | null
graded.holdRecallnumber | null

401 — Bearer token missing or unknown. Error

FieldTypeNotes
errorstringWhat went wrong, in one sentence.
requestId (optional)stringPresent once the gateway is live: the X-Request-Id of the failed request.

Example

curl -s "https://skoor.ai/risk/api/preflight/stats?tenant=demo&days=30" \
  -H "Authorization: Bearer test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "X-Operator: you@bank.example"

get/api/preflight/{id}

One pre-flight answer with its request

AuthBearer + X-Operator
OperationPre-flight · GET /api/preflight/{id}

Parameters

NameInTypeNotes
idpathstring (uuid)Pre-flight id.
tenant (optional)querystringTenant slug. Optional: the bearer token already proves the tenant. Pass it to be explicit.

Responses

200 — The stored answer, the request as submitted, and the matched transfer when one landed. PreflightDetail

FieldTypeNotes
preflightIdstring (uuid)
decision"clear" | "review" | "hold"
skoorinteger | null
band"clear" | "review" | "hold" | "unscored"
versionstring
ninteger
confidencenumber | null
reasonsReason[]
limitsHitLimitHit[]
degradedboolean
degradedReasonsstring[]
latencyMsinteger
idempotentboolean
programIdstring (uuid)
requestobjectThe request as submitted plus operator and resolved {entityId, counterpartyId, counterpartyCountry}.
matchedTransferIdstring | nullSet when the transfer later landed and was matched back (same program, counterparty, amount, within 24h).
createdAtstring (date-time)

401 — Bearer token missing or unknown. Error

FieldTypeNotes
errorstringWhat went wrong, in one sentence.
requestId (optional)stringPresent once the gateway is live: the X-Request-Id of the failed request.

404 — Unknown pre-flight on this tenant. Error

FieldTypeNotes
errorstringWhat went wrong, in one sentence.
requestId (optional)stringPresent once the gateway is live: the X-Request-Id of the failed request.

Example

curl -s "https://skoor.ai/risk/api/preflight/5f3c1c8e-2a44-4c0b-9d0f-2b0a2f6e7c11?tenant=demo" \
  -H "Authorization: Bearer test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "X-Operator: you@bank.example"

← All objects