Scenarios API¶
The Scenarios API enables what-if trade simulation, allowing you to model the compliance impact of proposed trades before execution.
Overview¶
What-if scenarios allow portfolio managers to:
- Simulate trades: Model buy/sell transactions against current portfolio
- Analyze impact: See how trades affect compliance test results
- Compare results: View before/after compliance status
- Make decisions: Get data-driven insights for trade execution
Endpoints¶
List Scenarios¶
Get all scenarios for the current tenant.
Query Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
page_size | integer | 20 | Items per page (max 100) |
status_filter | string | - | Filter by status (draft, calculating, completed, failed) |
Example Request¶
Response¶
{
"items": [
{
"id": "990e8400-e29b-41d4-a716-446655440010",
"name": "Q1 2026 Portfolio Optimization",
"description": "Test impact of selling low-rated assets",
"status": "completed",
"base_workbook_id": "550e8400-e29b-41d4-a716-446655440000",
"trade_count": 5,
"created_by": "user@example.com",
"created_at": "2026-01-25T09:00:00Z",
"updated_at": "2026-01-25T10:30:00Z"
}
],
"total": 12,
"page": 1,
"page_size": 20,
"pages": 1
}
Create Scenario¶
Create a new what-if scenario with optional initial trades.
Request Body¶
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Scenario name (1-200 chars) |
description | string | No | Scenario description (max 2000 chars) |
base_workbook_id | string (UUID) | No | Base workbook for calculations |
trades | array[Trade] | No | Initial trades to add |
Trade Object¶
| Field | Type | Required | Description |
|---|---|---|---|
trade_type | string | Yes | "buy" or "sell" |
cusip | string | No | CUSIP identifier |
borrower_name | string | No | Borrower/obligor name |
par_value | number | Yes | Par value of the trade |
price | number | No | Trade price (percentage of par) |
spread | number | No | Interest rate spread |
rating_moodys | string | No | Moody's rating |
rating_sp | string | No | S&P rating |
rating_fitch | string | No | Fitch rating |
industry | string | No | Industry classification |
maturity_date | string (date) | No | Loan maturity date |
loan_data | object | No | Additional loan attributes |
Example Request¶
curl -X POST https://api.calcbridge.io/api/v1/scenarios \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Q1 2026 Portfolio Optimization",
"description": "Test impact of selling low-rated assets and buying high-quality loans",
"base_workbook_id": "550e8400-e29b-41d4-a716-446655440000",
"trades": [
{
"trade_type": "sell",
"cusip": "OLD123ABC",
"borrower_name": "Weak Corp",
"par_value": 500000.00,
"rating_moodys": "Caa2"
},
{
"trade_type": "buy",
"cusip": "NEW456DEF",
"borrower_name": "Strong Corp",
"par_value": 500000.00,
"rating_moodys": "Ba2",
"spread": 2.5
}
]
}'
import requests
response = requests.post(
"https://api.calcbridge.io/api/v1/scenarios",
headers={"Authorization": f"Bearer {token}"},
json={
"name": "Q1 2026 Portfolio Optimization",
"description": "Test impact of selling low-rated assets",
"base_workbook_id": "550e8400-e29b-41d4-a716-446655440000",
"trades": [
{
"trade_type": "sell",
"cusip": "OLD123ABC",
"borrower_name": "Weak Corp",
"par_value": 500000.00,
"rating_moodys": "Caa2"
},
{
"trade_type": "buy",
"cusip": "NEW456DEF",
"borrower_name": "Strong Corp",
"par_value": 500000.00,
"rating_moodys": "Ba2",
"spread": 2.5
}
]
}
)
scenario = response.json()
print(f"Created scenario: {scenario['id']}")
const response = await fetch('https://api.calcbridge.io/api/v1/scenarios', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Q1 2026 Portfolio Optimization',
description: 'Test impact of selling low-rated assets',
base_workbook_id: '550e8400-e29b-41d4-a716-446655440000',
trades: [
{
trade_type: 'sell',
cusip: 'OLD123ABC',
borrower_name: 'Weak Corp',
par_value: 500000.00,
rating_moodys: 'Caa2'
},
{
trade_type: 'buy',
cusip: 'NEW456DEF',
borrower_name: 'Strong Corp',
par_value: 500000.00,
rating_moodys: 'Ba2',
spread: 2.5
}
]
})
});
const scenario = await response.json();
console.log('Created scenario:', scenario.id);
Response¶
{
"id": "990e8400-e29b-41d4-a716-446655440010",
"name": "Q1 2026 Portfolio Optimization",
"description": "Test impact of selling low-rated assets and buying high-quality loans",
"status": "draft",
"base_workbook_id": "550e8400-e29b-41d4-a716-446655440000",
"trade_count": 2,
"created_by": "user@example.com",
"created_at": "2026-01-25T09:00:00Z",
"updated_at": "2026-01-25T09:00:00Z"
}
Get Scenario¶
Retrieve scenario details.
Path Parameters¶
| Parameter | Type | Description |
|---|---|---|
scenario_id | string (UUID) | Scenario identifier |
Example Request¶
Response¶
{
"id": "990e8400-e29b-41d4-a716-446655440010",
"name": "Q1 2026 Portfolio Optimization",
"description": "Test impact of selling low-rated assets",
"status": "completed",
"base_workbook_id": "550e8400-e29b-41d4-a716-446655440000",
"trade_count": 2,
"created_by": "user@example.com",
"created_at": "2026-01-25T09:00:00Z",
"updated_at": "2026-01-25T10:30:00Z"
}
Add Trade to Scenario¶
Add a trade to an existing scenario.
Path Parameters¶
| Parameter | Type | Description |
|---|---|---|
scenario_id | string (UUID) | Scenario identifier |
Request Body¶
See Trade Object above.
Example Request¶
curl -X POST https://api.calcbridge.io/api/v1/scenarios/990e8400-e29b-41d4-a716-446655440010/trades \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"trade_type": "buy",
"cusip": "ADD789GHI",
"borrower_name": "Additional Corp",
"par_value": 250000.00,
"rating_moodys": "B1",
"spread": 3.25,
"industry": "Technology"
}'
import requests
response = requests.post(
f"https://api.calcbridge.io/api/v1/scenarios/{scenario_id}/trades",
headers={"Authorization": f"Bearer {token}"},
json={
"trade_type": "buy",
"cusip": "ADD789GHI",
"borrower_name": "Additional Corp",
"par_value": 250000.00,
"rating_moodys": "B1",
"spread": 3.25,
"industry": "Technology"
}
)
trade = response.json()
print(f"Added trade: {trade['id']}")
const response = await fetch(
`https://api.calcbridge.io/api/v1/scenarios/${scenarioId}/trades`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
trade_type: 'buy',
cusip: 'ADD789GHI',
borrower_name: 'Additional Corp',
par_value: 250000.00,
rating_moodys: 'B1',
spread: 3.25,
industry: 'Technology'
})
}
);
const trade = await response.json();
console.log('Added trade:', trade.id);
Response¶
{
"id": "aa0e8400-e29b-41d4-a716-446655440020",
"scenario_id": "990e8400-e29b-41d4-a716-446655440010",
"trade_type": "buy",
"cusip": "ADD789GHI",
"borrower_name": "Additional Corp",
"par_value": 250000.00,
"price": null,
"spread": 3.25,
"rating_moodys": "B1",
"rating_sp": null,
"rating_fitch": null,
"industry": "Technology",
"maturity_date": null,
"created_at": "2026-01-25T09:15:00Z"
}
List Scenario Trades¶
Get all trades in a scenario.
Path Parameters¶
| Parameter | Type | Description |
|---|---|---|
scenario_id | string (UUID) | Scenario identifier |
Example Request¶
Response¶
[
{
"id": "aa0e8400-e29b-41d4-a716-446655440021",
"scenario_id": "990e8400-e29b-41d4-a716-446655440010",
"trade_type": "sell",
"cusip": "OLD123ABC",
"borrower_name": "Weak Corp",
"par_value": 500000.00,
"rating_moodys": "Caa2",
"created_at": "2026-01-25T09:00:00Z"
},
{
"id": "aa0e8400-e29b-41d4-a716-446655440022",
"scenario_id": "990e8400-e29b-41d4-a716-446655440010",
"trade_type": "buy",
"cusip": "NEW456DEF",
"borrower_name": "Strong Corp",
"par_value": 500000.00,
"rating_moodys": "Ba2",
"spread": 2.5,
"created_at": "2026-01-25T09:00:00Z"
}
]
Remove Trade¶
Remove a trade from a scenario.
Path Parameters¶
| Parameter | Type | Description |
|---|---|---|
scenario_id | string (UUID) | Scenario identifier |
trade_id | string (UUID) | Trade identifier |
Example Request¶
Response¶
Returns 204 No Content on success.
Run Simulation¶
Execute the scenario simulation and calculate compliance impact.
Path Parameters¶
| Parameter | Type | Description |
|---|---|---|
scenario_id | string (UUID) | Scenario identifier |
Example Request¶
Response¶
{
"scenario_id": "990e8400-e29b-41d4-a716-446655440010",
"status": "completed",
"results": [
{
"test_name": "Single Obligor Concentration",
"test_category": "concentration",
"current_value": 4.2,
"projected_value": 4.1,
"threshold_value": 5.0,
"cushion_current": 0.8,
"cushion_projected": 0.9,
"status_current": "pass",
"status_projected": "pass",
"impact_direction": "improve"
},
{
"test_name": "CCC Rated Assets",
"test_category": "rating",
"current_value": 8.5,
"projected_value": 6.2,
"threshold_value": 7.5,
"cushion_current": -1.0,
"cushion_projected": 1.3,
"status_current": "fail",
"status_projected": "pass",
"impact_direction": "improve"
},
{
"test_name": "Weighted Average Spread",
"test_category": "portfolio",
"current_value": 3.8,
"projected_value": 3.6,
"threshold_value": 3.0,
"cushion_current": 0.8,
"cushion_projected": 0.6,
"status_current": "pass",
"status_projected": "pass",
"impact_direction": "worsen"
}
],
"impact_summary": {
"improve": 2,
"worsen": 1,
"neutral": 12
},
"new_failures": 0,
"total_tests": 15,
"message": "Simulation completed: 2 trades applied to 150 loans"
}
Get Simulation Results¶
Retrieve saved simulation results.
Path Parameters¶
| Parameter | Type | Description |
|---|---|---|
scenario_id | string (UUID) | Scenario identifier |
Query Parameters¶
| Parameter | Type | Description |
|---|---|---|
category | string | Filter by test category |
Example Request¶
Response¶
[
{
"test_name": "CCC Rated Assets",
"test_category": "rating",
"current_value": 8.5,
"projected_value": 6.2,
"threshold_value": 7.5,
"cushion_current": -1.0,
"cushion_projected": 1.3,
"status_current": "fail",
"status_projected": "pass",
"impact_direction": "improve"
},
{
"test_name": "Average Rating Factor",
"test_category": "rating",
"current_value": 2450,
"projected_value": 2380,
"threshold_value": 2600,
"cushion_current": 150,
"cushion_projected": 220,
"status_current": "pass",
"status_projected": "pass",
"impact_direction": "improve"
}
]
Delete Scenario¶
Delete a scenario and all associated trades and results.
Path Parameters¶
| Parameter | Type | Description |
|---|---|---|
scenario_id | string (UUID) | Scenario identifier |
Example Request¶
Response¶
Returns 204 No Content on success.
Scenario Status¶
| Status | Description |
|---|---|
draft | Scenario created, awaiting simulation |
calculating | Simulation in progress |
completed | Simulation finished successfully |
failed | Simulation encountered an error |
Impact Direction¶
| Direction | Description |
|---|---|
improve | Projected value moves closer to passing |
worsen | Projected value moves closer to failing |
neutral | No significant change in compliance position |
Best Practices¶
- Use descriptive names: Make scenarios easy to identify later
- Include all relevant trades: Simulate the complete trade package together
- Review results before execution: Pay attention to new failures
- Compare multiple scenarios: Create variations to find optimal trades
- Archive completed scenarios: Keep historical records for audit trails