# 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, and oracle exposures.

### Query Parameters

| Parameter | Type   | Default  | Description                                                 |
| --------- | ------ | -------- | ----------------------------------------------------------- |
| vaults    | string | required | Comma-separated `{chainId}:{lowercaseAddress}` keys, max 50 |

### Example

```bash
curl "https://api.philidor.io/v1/graph/look-through?vaults=1:0x1111111111111111111111111111111111111111" \
  -H "Authorization: Bearer pk_live_your_key_here"
```

### Response

```json
{
  "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": [],
        "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 by curator, protocol, chain, asset, or oracle |
| issue        | boolean | Whether to issue a signed decision                                      |
| loss         | object  | Optional org-modeled loss payload to attest                             |

### Example

```bash
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 },
    "issue": true
  }'
```

### Response

```json
{
  "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 breach preview from borrower health books. Bounds on liquidatable debt are not loss estimates and cannot back sizing decisions.

### Example

```bash
curl https://api.philidor.io/v1/graph/breach \
  -H "Authorization: Bearer pk_live_your_key_here"
```

### Response

```json
{
  "data": {
    "observedAt": "2026-07-01T00:00:00Z",
    "protocolId": "morpho",
    "maturity": "preview",
    "shockPcts": [10, 20],
    "chains": [],
    "topMarkets": []
  }
}
```

## 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

```bash
curl "https://api.philidor.io/v1/graph/incident-exposure?vaults=1:0x1111111111111111111111111111111111111111" \
  -H "Authorization: Bearer pk_live_your_key_here"
```

### Response

```json
{
  "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

```bash
curl https://api.philidor.io/v1/graph/incident-exposure/summary \
  -H "Authorization: Bearer pk_live_your_key_here"
```

### Response

```json
{
  "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

```bash
curl https://api.philidor.io/v1/graph/decision/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/verify
```

### Response

```json
{
  "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

```bash
curl https://api.philidor.io/v1/graph/snapshot/ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
```

### Response

```json
{
  "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.