Reference

API reference

Every endpoint, grouped by module. Conventions common to all of them — coverage, as-of block, reason codes, idempotency — are in the overview rather than repeated here.

Sentinel — screening

POST/v1/screen/address

Screen an address

Returns a weighted risk score, the reason codes behind it, sanctions state and an evidence reference. Repeat screens of the same address within 24 hours are served from cache and billed once.

ParameterTypeNotes
chainstring, requiredethereum · solana · tron · base · arbitrum · polygon · bsc
addressstring, requiredChecksummed or lowercase. Validated per chain.
trace_depthinteger, 1–6Hops to walk. Default 4. Higher is slower and finds more distant exposure.
include_evidencebooleanDefault true. Set false to skip evidence generation and shave latency.
Request
{
  "chain": "ethereum",
  "address": "0x7a25…f3b1",
  "trace_depth": 4
}
Response
{
  "risk_score": 71,
  "band": "elevated",
  "reasons": [ { "code": "MIXER_PROXIMITY",
    "weight": 34, "hops": 2 } ],
  "sanctions": { "match": false },
  "as_of_block": 20914773,
  "coverage": { "chains": ["ethereum"] },
  "evidence_url": "…/evidence/ev_3f…"
}
POST/v1/screen/transaction

Screen a transaction

Screens both sides of a transfer plus the path between them. Use this rather than two address calls when you care about the transfer itself — it costs less than two calls and returns path-specific reasons an address screen cannot.

ParameterTypeNotes
tx_hashstring, requiredTransaction hash. Must exist on the named chain.
perspectivestringWhich side you are. sender · receiver. Default inferred from your registered addresses.
Request
{
  "chain": "tron",
  "tx_hash": "9f2c…a410"
}
Response
{
  "risk_score": 44,
  "band": "watch",
  "direction": "inbound",
  "counterparty": { "address": "TQ8x…v2",
    "cluster": "exchange-deposit",
    "confidence": 0.91 },
  "reasons": [ … ],
  "as_of_block": 65310022
}
GET/v1/screen/evidence/{id}

Retrieve an evidence trail

Resolves the evidence reference from a score into the transfer paths that produced each reason code. Retained for 12 months by default; this is what you hand an auditor.

Request
GET /v1/screen/evidence/ev_3f…
Authorization: Bearer …
Response
{
  "score_at_issue": 71,
  "issued_at": "2026-07-30T09:12:44Z",
  "paths": [
    { "reason": "MIXER_PROXIMITY",
      "transfers": [ { "tx": "0x4c…", "value": "12.4",
        "asset": "ETH" }, … ] }
  ]
}
POST/v1/screen/batch

Batch screen

Up to 10,000 addresses per submission, processed asynchronously. Use for onboarding backfills rather than looping the single-address endpoint.

Request
{
  "chain": "ethereum",
  "addresses": ["0x7a…", "0x91…", …],
  "callback_url": "https://yourapp/hooks/batch"
}
Response
{
  "batch_id": "bat_8Kq…",
  "accepted": 9841,
  "rejected": 159,
  "status": "processing"
}

CreditGraph — credit

POST/v1/credit/profile

Build a credit profile

Reconstructs borrowing history across supported lending protocols and returns underwriting signals. Returns thin_file: true rather than a fabricated grade where history is too sparse.

ParameterTypeNotes
lookback_daysintegerDefault 540. Use 0 for full available history.
as_ofstring, RFC 3339Point-in-time replay: the profile as it would have been on this date. Essential for fair backtesting.
protocolsarrayRestrict to named protocols. Default all supported.
Request
{
  "chain": "ethereum",
  "address": "0x91cd…8ee0",
  "lookback_days": 540
}
Response
{
  "tier": "B+",
  "signals": {
    "repayment_events": 47,
    "repayment_ratio": 0.98,
    "liquidations_suffered": 1,
    "min_health_factor_90d": 1.34,
    "protocol_concentration": 0.62
  },
  "thin_file": false,
  "as_of_block": 20914773
}
GET/v1/credit/positions

List open positions

Current borrows, collateral and health factors per protocol. Useful for monitoring an existing book rather than underwriting a new one.

Request
GET /v1/credit/positions
  ?chain=ethereum&address=0x91cd…8ee0
Response
{
  "positions": [
    { "protocol": "aave-v3", "borrowed_usd": "412000.00",
      "collateral_usd": "690000.00",
      "health_factor": 1.41 }
  ],
  "aggregate_health_factor": 1.41
}
POST/v1/credit/monitor

Monitor a wallet

Registers a wallet for continuous monitoring. Deterioration in health factor, a new liquidation or a concentration shift fires a webhook.

Request
{
  "chain": "ethereum",
  "address": "0x91cd…8ee0",
  "alert_on": { "health_factor_below": 1.15 }
}
Response
{
  "monitor_id": "mon_2Bd…",
  "active": true
}

PayRoute — routing

POST/v1/route/quote

Quote settlement routes

Ranked routes with itemised landed cost. Every candidate destination is screened first; routes that fail screening appear in withheld[] with a reason, never silently omitted.

ParameterTypeNotes
amountstring, requiredDecimal string. Never a float.
rank_bystringlanded_cost · speed · custom. Custom uses your contracted weights.
max_chainsarrayRestrict candidates. Combine with a bridge allowlist for tight control.
Request
{
  "asset": "USDT",
  "amount": "250000.00",
  "destination": { "chain": "tron",
    "address": "TQ8x…v2" },
  "rank_by": "landed_cost"
}
Response
{
  "quote_id": "qte_5Hn…",
  "routes": [
    { "rank": 1, "chain": "tron",
      "landed_cost_usd": "3.41",
      "eta_seconds": 55, "risk_band": "clear" }
  ],
  "withheld": [],
  "quote_expires_at": "2026-07-30T11:42:06Z"
}
POST/v1/route/execute

Execute against a quote

Executes the chosen route. Requires an Idempotency-Key; a retry with the same key returns the original result rather than sending twice. Executing after quote expiry fails rather than re-pricing silently.

Request
Idempotency-Key: payout-20614

{
  "quote_id": "qte_5Hn…",
  "route_rank": 1
}
Response
{
  "payout_id": "pay_9Cm…",
  "status": "submitted",
  "tx_hash": "9f2c…a410",
  "quoted_cost_usd": "3.41"
}
GET/v1/route/payouts/{id}

Payout status

Confirmation depth and final on-chain cost against what was quoted. This is the record you reconcile against.

Request
GET /v1/route/payouts/pay_9Cm…
Response
{
  "status": "settled",
  "confirmations": 41,
  "actual_cost_usd": "3.38",
  "quoted_cost_usd": "3.41",
  "settled_at": "2026-07-30T11:38:02Z"
}

Ledger Mind — treasury

GET/v1/treasury/reconciliation

Period reconciliation

Matched totals, unmatched items with a suggested cause, and every multisig policy event in the window. An approved_by of null is a signer change with no recorded approval — alert on it.

ParameterTypeNotes
periodstring, requiredYYYY-MM. Must be a period you have mapped.
include_matchedbooleanDefault false. True returns all matched pairs — large payload.
Request
GET /v1/treasury/reconciliation
  ?period=2026-06
Response
{
  "period": "2026-06",
  "matched": { "count": 1841,
    "value_usd": "48219004.11" },
  "unmatched": [
    { "kind": "on_chain_only", "tx": "0x4c1a…",
      "suggestion": "fee rebate — no ledger entry" }
  ],
  "policy_events": [
    { "kind": "SIGNER_ADDED", "approved_by": null }
  ],
  "close_pack_url": "…/close/2026-06.pdf"
}
POST/v1/treasury/addresses

Map an address

Registers a wallet, multisig or exchange sub-account against your chart of accounts. Internal-transfer pairs declared here stop treasury movement being counted as revenue.

Request
{
  "chain": "solana",
  "address": "7xKX…9fT",
  "label": "Ops hot wallet",
  "gl_account": "1120",
  "internal": true
}
Response
{
  "address_id": "adr_4Tp…",
  "watching": true,
  "backfill_started": true
}
POST/v1/treasury/exceptions/{id}/resolve

Resolve an exception

Records who resolved an unmatched item and how. Appends to an immutable audit log and regenerates the close pack.

Request
{
  "resolution": "matched_manually",
  "ledger_entry": "JE-20614",
  "note": "Posted to wrong wallet, corrected."
}
Response
{
  "resolved": true,
  "resolved_by": "u_88Kd…",
  "close_pack_regenerated": true
}

Versioning headers

HeaderPurpose
X-FTAI-Scoring-VersionPin the Sentinel scoring methodology. Omit for current. Pinned versions are supported for the window announced in the changelog.
Idempotency-KeyRequired on execute, accepted on any state-changing call. Retained 24 hours.
X-FTAI-Request-IdReturned on every response. Quote it in support requests — it resolves to the exact call.
X-FTAI-RateLimit-*Remaining and Reset on every response including errors. See errors and limits.