Risk Graph
Limited-release Decisioning endpoints for look-through, checks, breach preview, incident exposure, and public decision verification.
The Risk Graph API is in limited release and enabled per arrangement. Look-through, check, breach, and incident-exposure endpoints require a growth or enterprise key. Decision verification is public by design when the graph feature is enabled.
Signed decisions bind a verdict to a content-addressed snapshot ID, methodology version, and EIP-191 signature. Counterparties can verify the envelope without receiving the customer's API key.
GET /v1/graph/look-through
Resolve vaults to underlying curator, protocol, chain, asset, wrapper, oracle, bridge, and
administrative signer-set exposures. Bridge and signer-set references include verified and
confidence fields so consumers can distinguish source-backed mappings from provisional ones.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| vaults | string | required | Comma-separated {chainId}:{lowercaseAddress} keys, max 50 |
Example
curl "https://api.philidor.io/v1/graph/look-through?vaults=1:0x1111111111111111111111111111111111111111" \
-H "Authorization: Bearer pk_live_your_key_here"Response
{
"data": {
"snapshotId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"builtAt": "2026-07-01T00:00:00Z",
"validTime": "2026-07-01T00:00:00Z",
"results": {
"1:0x1111111111111111111111111111111111111111": {
"vaultKey": "1:0x1111111111111111111111111111111111111111",
"curator": "gauntlet",
"protocol": "morpho",
"chain": "ethereum",
"assets": [
{
"assetKey": "1:0x2260fac5e5542a773aa44fbcfedf7c193bc2c599",
"symbol": "WBTC",
"usdExposure": "1000000.00",
"wrappers": [],
"oracles": [],
"bridges": [{ "id": "bridge:wbtc-bitgo", "verified": true, "confidence": 1 }]
}
],
"signerSets": [{ "id": "signer_set:morpho-dao", "verified": false, "confidence": 0.5 }],
"cycles": []
}
}
}
}POST /v1/graph/check
Evaluate a portfolio against exposure limits. issue=true persists a signed decision when server-side signing is configured.
Body
| Field | Type | Description |
|---|---|---|
| portfolioRef | string | Customer portfolio reference |
| positions | array | Vault keys and USD amounts |
| limits | object | Optional max-share limits; see supported dimensions below |
| issue | boolean | Whether to issue a signed decision |
Supported limit fields are fractions in (0, 1]:
| Field | Exposure grouped by |
|---|---|
maxSharePerCurator | Vault curator |
maxSharePerProtocol | Protocol |
maxSharePerChain | Chain |
maxSharePerAsset | Underlying collateral asset |
maxSharePerOracle | Individual oracle feed |
maxSharePerOracleVendor | Shared oracle operator/vendor |
maxSharePerCluster | Correlated operator cluster |
maxSharePerBridge | Bridge or custody route |
maxSharePerSignerSet | Administrative signer set, Safe, timelock, or executor |
Bridge exposure is attributed in proportion to each vault's bridged collateral. Signer-set
exposure applies to the whole administered vault position. Findings carry verified and
confidence: an unverified-only bridge or signer-set breach is advisory and can produce
caution, but it cannot produce an authoritative reject by itself.
Signed decisions bind the portfolio, graph snapshot, limits, verdict, findings, methodology and signer. Scenario estimates are intentionally excluded from the signed payload.
Example
curl -X POST https://api.philidor.io/v1/graph/check \
-H "Authorization: Bearer pk_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"portfolioRef": "portfolio-1",
"positions": [
{ "vaultKey": "1:0x1111111111111111111111111111111111111111", "amountUsd": 1000000 }
],
"limits": {
"maxSharePerProtocol": 0.5,
"maxSharePerBridge": 0.3,
"maxSharePerSignerSet": 0.35
},
"issue": true
}'Response
{
"data": {
"snapshotId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"builtAt": "2026-07-01T00:00:00Z",
"verdict": "approve",
"totalUsd": "1000000",
"unresolvedVaults": [],
"findings": [],
"exposures": {},
"decision": {
"decisionId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"signerAddress": "0x...",
"inserted": true
}
}
}GET /v1/graph/breach
Return the latest multi-protocol breach preview from borrower health books. protocols[] is the authoritative set; the top-level Morpho fields are deprecated aliases retained for compatibility and must not be added to protocol totals.
Morpho, Aave V3, and SparkLend are labeled independently. Their multi-request reads are interval_sampled, with explicit sweep boundaries and no point-in-time lower-bound claim. Morpho and Aave use official protocol APIs; SparkLend uses bounded on-chain RPC reads (source: "onchain_rpc"). unpricedDebtUsd is debt excluded from projected loss because collateral valuation was incomplete; treat it as unknown, not zero. Bounds on liquidatable debt are not loss estimates and cannot back sizing decisions.
Example
curl https://api.philidor.io/v1/graph/breach \
-H "Authorization: Bearer pk_live_your_key_here"Response
{
"data": {
"schemaVersion": 2,
"observedAt": "2026-07-01T00:00:00Z",
"protocolId": "morpho",
"source": "protocol_api",
"maturity": "preview",
"shockPcts": [5, 10, 25],
"chains": [],
"topMarkets": [],
"protocols": [
{
"observedAt": "2026-07-01T00:00:00Z",
"protocolId": "morpho",
"source": "protocol_api",
"maturity": "preview",
"sweepStartedAt": "2026-06-30T23:55:00Z",
"sweepCompletedAt": "2026-07-01T00:00:00Z",
"shockPcts": [5, 10, 25],
"coverage": {
"status": "interval_sampled",
"methodology": "largest-position-api-window",
"reason": "Unpinned, deduplicated offset-page sweep."
},
"chains": [],
"topMarkets": [],
"topVaultExposures": [],
"vaultBadDebt": []
},
{
"observedAt": "2026-07-01T00:00:00Z",
"protocolId": "aave",
"source": "protocol_api",
"maturity": "preview",
"sweepStartedAt": "2026-06-30T23:58:00Z",
"sweepCompletedAt": "2026-07-01T00:00:00Z",
"shockPcts": [5, 10, 25],
"coverage": {
"status": "interval_sampled",
"methodology": "top-holder-sample",
"reason": "Bounded top-aToken-holder account sample."
},
"chains": [],
"topMarkets": [],
"topVaultExposures": [],
"vaultBadDebt": []
},
{
"observedAt": "2026-07-01T00:00:00Z",
"protocolId": "spark",
"source": "onchain_rpc",
"maturity": "preview",
"sweepStartedAt": "2026-06-30T23:58:00Z",
"sweepCompletedAt": "2026-07-01T00:00:00Z",
"shockPcts": [5, 10, 25],
"coverage": {
"status": "interval_sampled",
"methodology": "top-holder-sample",
"reason": "Bounded top-aToken-holder on-chain account sample."
},
"chains": [],
"topMarkets": [],
"topVaultExposures": [],
"vaultBadDebt": []
}
]
}
}GET /v1/graph/incident-exposure
Return per-vault exposure to dependency issuers with incident history.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| vaults | string | required | Comma-separated vault keys |
Example
curl "https://api.philidor.io/v1/graph/incident-exposure?vaults=1:0x1111111111111111111111111111111111111111" \
-H "Authorization: Bearer pk_live_your_key_here"Response
{
"data": {
"snapshotId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"mapVersion": "v1",
"generatedAt": "2026-07-01T00:00:00Z",
"validTime": "2026-07-01T00:00:00Z",
"results": {}
}
}GET /v1/graph/incident-exposure/summary
Return issuer-level incident-exposure aggregates for the latest graph materialization.
Example
curl https://api.philidor.io/v1/graph/incident-exposure/summary \
-H "Authorization: Bearer pk_live_your_key_here"Response
{
"data": {
"snapshotId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"mapVersion": "v1",
"generatedAt": "2026-07-01T00:00:00Z",
"validTime": "2026-07-01T00:00:00Z",
"vaultCount": 10,
"issuerCount": 3,
"totalIncidentExposureUsd": "1000000",
"issuers": []
}
}GET /v1/graph/decision/{id}/verify
Verify a signed decision. This route is public by design so counterparties can verify the artifact without a Philidor API key. It still returns 404 when the graph feature is disabled.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| id | string | Decision envelope hash, 64 hex characters |
Example
curl https://api.philidor.io/v1/graph/decision/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/verifyResponse
{
"data": {
"found": true,
"envelopeIntact": true,
"signatureValid": true,
"signerRecognized": true,
"signerActiveAtIssuance": true,
"decision": {
"id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"portfolioRef": "portfolio-1",
"snapshotId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"verdict": "approve",
"methodologyScope": "graph_check",
"methodologyVersion": "v1",
"signerAddress": "0x...",
"keyId": "key-1",
"createdAt": "2026-07-01T00:00:00Z"
}
}
}GET /v1/graph/snapshot/{id}
Return a public frozen snapshot manifest by snapshot ID. This route does not require a key when the graph feature is enabled.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| id | string | Snapshot hash, 64 hex characters |
Example
curl https://api.philidor.io/v1/graph/snapshot/ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffResponse
{
"data": {
"snapshotId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"builtAt": "2026-07-01T00:00:00Z",
"validTime": "2026-07-01T00:00:00Z",
"publications": [],
"cursors": {}
}
}Graph routes fail closed with 503 and Retry-After: 600 when required materialization is missing.