Skip to content

Reports API

The Reports API provides endpoints for generating, retrieving, and exporting compliance and portfolio reports.


Overview

CalcBridge's reporting system enables:

  • Automated Reports: Schedule regular compliance snapshots
  • On-Demand Generation: Create reports for specific workbooks
  • Multiple Formats: Export to PDF, Excel, CSV, or JSON
  • Custom Templates: Use predefined or custom report templates

Endpoints

Generate Report

Create a new report from a workbook.

POST /api/v1/reports/generate

Request Body

Field Type Required Description
workbook_id string (UUID) Yes Source workbook
report_type string Yes Type: compliance, portfolio, holdings, custom
template_id string No Custom template identifier
title string No Report title
options object No Report generation options

Options Object

Field Type Default Description
include_charts boolean true Include visualizations
include_raw_data boolean false Include raw data tables
date_range object - Filter by date range
sections array[string] - Specific sections to include
comparison_workbook_id string (UUID) - Workbook for comparison

Example Request

curl -X POST https://api.calcbridge.io/api/v1/reports/generate \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "workbook_id": "550e8400-e29b-41d4-a716-446655440000",
    "report_type": "compliance",
    "title": "Q1 2026 Compliance Report",
    "options": {
      "include_charts": true,
      "sections": ["summary", "concentration", "rating", "coverage"]
    }
  }'
import requests

response = requests.post(
    "https://api.calcbridge.io/api/v1/reports/generate",
    headers={"Authorization": f"Bearer {token}"},
    json={
        "workbook_id": "550e8400-e29b-41d4-a716-446655440000",
        "report_type": "compliance",
        "title": "Q1 2026 Compliance Report",
        "options": {
            "include_charts": True,
            "sections": ["summary", "concentration", "rating", "coverage"]
        }
    }
)
report = response.json()
print(f"Report ID: {report['id']}")
print(f"Status: {report['status']}")
const response = await fetch('https://api.calcbridge.io/api/v1/reports/generate', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    workbook_id: '550e8400-e29b-41d4-a716-446655440000',
    report_type: 'compliance',
    title: 'Q1 2026 Compliance Report',
    options: {
      include_charts: true,
      sections: ['summary', 'concentration', 'rating', 'coverage']
    }
  })
});
const report = await response.json();
console.log('Report ID:', report.id);
console.log('Status:', report.status);

Response

{
  "id": "bb0e8400-e29b-41d4-a716-446655440030",
  "workbook_id": "550e8400-e29b-41d4-a716-446655440000",
  "report_type": "compliance",
  "title": "Q1 2026 Compliance Report",
  "status": "generating",
  "progress": 0,
  "created_by": "user@example.com",
  "created_at": "2026-01-25T10:30:00Z",
  "estimated_completion": "2026-01-25T10:31:00Z"
}

Error Responses

Status Error Description
400 Invalid report type Unknown report_type value
404 Workbook not found Invalid workbook_id
404 Template not found Invalid template_id
409 Report already generating Duplicate report in progress

Get Report

Retrieve report details and content.

GET /api/v1/reports/{report_id}

Path Parameters

Parameter Type Description
report_id string (UUID) Report identifier

Query Parameters

Parameter Type Default Description
include_content boolean true Include full report content
section string - Return only specific section

Example Request

curl -X GET "https://api.calcbridge.io/api/v1/reports/bb0e8400-e29b-41d4-a716-446655440030?include_content=true" \
  -H "Authorization: Bearer $TOKEN"
import requests

response = requests.get(
    f"https://api.calcbridge.io/api/v1/reports/{report_id}",
    headers={"Authorization": f"Bearer {token}"},
    params={"include_content": True}
)
report = response.json()
print(f"Title: {report['title']}")
print(f"Status: {report['status']}")
if report['status'] == 'completed':
    print(f"Sections: {list(report['content'].keys())}")
const response = await fetch(
  `https://api.calcbridge.io/api/v1/reports/${reportId}?include_content=true`,
  { headers: { 'Authorization': `Bearer ${token}` } }
);
const report = await response.json();
console.log('Title:', report.title);
console.log('Status:', report.status);
if (report.status === 'completed') {
  console.log('Sections:', Object.keys(report.content));
}

Response (Completed)

{
  "id": "bb0e8400-e29b-41d4-a716-446655440030",
  "workbook_id": "550e8400-e29b-41d4-a716-446655440000",
  "report_type": "compliance",
  "title": "Q1 2026 Compliance Report",
  "status": "completed",
  "progress": 100,
  "content": {
    "summary": {
      "total_tests": 15,
      "passed": 13,
      "failed": 2,
      "warnings": 1,
      "overall_status": "attention_required",
      "generated_at": "2026-01-25T10:31:00Z"
    },
    "concentration": {
      "single_obligor": {
        "test_name": "Single Obligor Concentration",
        "current_value": 4.2,
        "threshold": 5.0,
        "status": "pass",
        "cushion": 0.8,
        "top_exposures": [
          {"name": "Acme Corp", "exposure": 4.2},
          {"name": "Tech Industries", "exposure": 3.8},
          {"name": "Global Services", "exposure": 3.5}
        ]
      },
      "industry": {
        "test_name": "Industry Concentration",
        "current_value": 12.5,
        "threshold": 15.0,
        "status": "pass",
        "cushion": 2.5
      }
    },
    "rating": {
      "ccc_bucket": {
        "test_name": "CCC Rated Assets",
        "current_value": 8.5,
        "threshold": 7.5,
        "status": "fail",
        "cushion": -1.0,
        "detail": "Exceeded by 1.0%"
      }
    },
    "coverage": {
      "oc_test": {
        "test_name": "Overcollateralization Test",
        "current_value": 125.5,
        "threshold": 120.0,
        "status": "pass",
        "cushion": 5.5
      }
    }
  },
  "metadata": {
    "workbook_name": "CLO Portfolio Q1 2026",
    "snapshot_date": "2026-01-25",
    "total_par": 100000000,
    "asset_count": 150
  },
  "created_by": "user@example.com",
  "created_at": "2026-01-25T10:30:00Z",
  "completed_at": "2026-01-25T10:31:00Z"
}

Response (Generating)

{
  "id": "bb0e8400-e29b-41d4-a716-446655440030",
  "status": "generating",
  "progress": 45,
  "current_step": "Processing rating tests",
  "estimated_completion": "2026-01-25T10:31:00Z"
}

Export Report

Export a completed report to various formats.

POST /api/v1/reports/{report_id}/export

Path Parameters

Parameter Type Description
report_id string (UUID) Report identifier

Request Body

Field Type Required Description
format string Yes Export format: pdf, xlsx, csv, json
options object No Format-specific options

Format Options

PDF Options:

Field Type Default Description
page_size string letter Page size: letter, a4, legal
orientation string portrait Orientation: portrait, landscape
include_cover boolean true Include cover page
include_toc boolean true Include table of contents

Excel Options:

Field Type Default Description
include_formulas boolean false Include calculation formulas
include_charts boolean true Include embedded charts
sheet_per_section boolean true Separate sheet per section

Example Request

curl -X POST https://api.calcbridge.io/api/v1/reports/bb0e8400-e29b-41d4-a716-446655440030/export \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "format": "pdf",
    "options": {
      "page_size": "letter",
      "orientation": "portrait",
      "include_cover": true,
      "include_toc": true
    }
  }'
import requests

response = requests.post(
    f"https://api.calcbridge.io/api/v1/reports/{report_id}/export",
    headers={"Authorization": f"Bearer {token}"},
    json={
        "format": "pdf",
        "options": {
            "page_size": "letter",
            "include_cover": True
        }
    }
)
export_info = response.json()

# Download the file
download_response = requests.get(
    export_info["download_url"],
    headers={"Authorization": f"Bearer {token}"}
)
with open("report.pdf", "wb") as f:
    f.write(download_response.content)
const response = await fetch(
  `https://api.calcbridge.io/api/v1/reports/${reportId}/export`,
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      format: 'pdf',
      options: {
        page_size: 'letter',
        include_cover: true
      }
    })
  }
);
const exportInfo = await response.json();

// Download the file
const downloadResponse = await fetch(exportInfo.download_url, {
  headers: { 'Authorization': `Bearer ${token}` }
});
const blob = await downloadResponse.blob();
// Save or process the blob

Response

{
  "export_id": "cc0e8400-e29b-41d4-a716-446655440040",
  "report_id": "bb0e8400-e29b-41d4-a716-446655440030",
  "format": "pdf",
  "status": "completed",
  "file_name": "Q1_2026_Compliance_Report.pdf",
  "file_size": 524288,
  "download_url": "https://api.calcbridge.io/api/v1/reports/bb0e8400-e29b-41d4-a716-446655440030/download/cc0e8400-e29b-41d4-a716-446655440040",
  "expires_at": "2026-01-25T11:30:00Z"
}

Error Responses

Status Error Description
400 Invalid format Unsupported export format
400 Report not completed Report is still generating
404 Report not found Invalid report_id

List Reports

Get all reports for the current tenant.

GET /api/v1/reports

Query Parameters

Parameter Type Default Description
page integer 1 Page number
page_size integer 20 Items per page
workbook_id string (UUID) - Filter by workbook
report_type string - Filter by type
status string - Filter by status
start_date string (ISO 8601) - Reports after this date
end_date string (ISO 8601) - Reports before this date

Example Request

curl -X GET "https://api.calcbridge.io/api/v1/reports?report_type=compliance&page_size=10" \
  -H "Authorization: Bearer $TOKEN"

Response

{
  "items": [
    {
      "id": "bb0e8400-e29b-41d4-a716-446655440030",
      "workbook_id": "550e8400-e29b-41d4-a716-446655440000",
      "report_type": "compliance",
      "title": "Q1 2026 Compliance Report",
      "status": "completed",
      "created_by": "user@example.com",
      "created_at": "2026-01-25T10:30:00Z"
    },
    {
      "id": "bb0e8400-e29b-41d4-a716-446655440031",
      "workbook_id": "550e8400-e29b-41d4-a716-446655440000",
      "report_type": "compliance",
      "title": "Weekly Compliance Snapshot",
      "status": "completed",
      "created_by": "user@example.com",
      "created_at": "2026-01-18T10:00:00Z"
    }
  ],
  "total": 25,
  "page": 1,
  "page_size": 10,
  "total_pages": 3
}

Delete Report

Delete a report and associated exports.

DELETE /api/v1/reports/{report_id}

Path Parameters

Parameter Type Description
report_id string (UUID) Report identifier

Example Request

curl -X DELETE https://api.calcbridge.io/api/v1/reports/bb0e8400-e29b-41d4-a716-446655440030 \
  -H "Authorization: Bearer $TOKEN"

Response

Returns 204 No Content on success.


Report Types

Type Description Sections
compliance Compliance test results Summary, Concentration, Rating, Coverage, Portfolio
portfolio Portfolio composition analysis Summary, Holdings, Allocation, Metrics
holdings Detailed holdings list Full loan/asset listing with attributes
custom User-defined template Varies by template

Report Status

Status Description
pending Report queued for generation
generating Report is being generated
completed Report ready for viewing/export
failed Generation encountered an error

Best Practices

  1. Check status before export: Ensure report is completed before exporting
  2. Use appropriate formats: PDF for sharing, Excel for further analysis
  3. Archive important reports: Export and save critical compliance reports
  4. Schedule regular reports: Set up automated compliance snapshots
  5. Include comparison data: Use comparison_workbook_id for trend analysis