Developer/Integrator Guide¶
Role Overview¶
As a Developer or Integrator, you are responsible for:
- Building integrations that connect CalcBridge with other systems
- Automating workflows using the CalcBridge API
- Extending functionality through custom dashboards and tools
- Monitoring and debugging integration health
CalcBridge provides a comprehensive REST API with JWT and API key authentication, detailed documentation, and code examples in multiple languages.
What CalcBridge Does for You
- Full-featured REST API with OpenAPI specification
- Dual authentication (JWT for users, API keys for services)
- Webhook notifications for async events
- Batch operations for high-volume processing
Daily Workflow¶
flowchart LR
A[Review API Docs] --> B[Build Integration]
B --> C[Test & Debug]
C --> D[Monitor Health]
D --> E[Iterate & Improve]
style A fill:#DBEAFE,stroke:#3B82F6
style B fill:#DCFCE7,stroke:#22C55E
style C fill:#FEF3C7,stroke:#F59E0B
style D fill:#FEE2E2,stroke:#EF4444
style E fill:#EDE9FE,stroke:#8B5CF6 Step 1: Review API Documentation¶
Familiarize yourself with available endpoints and data models:
- OpenAPI specification at
/docs - Interactive API explorer at
/redoc - Code examples in this guide
Step 2: Build Integration¶
Develop your integration using the patterns and examples provided.
Step 3: Test and Debug¶
Use the sandbox environment and debugging tools to verify functionality.
Step 4: Monitor Health¶
Set up monitoring for API calls and error rates.
Step 5: Iterate and Improve¶
Continuously improve based on usage patterns and user feedback.
Key Features¶
REST API¶
Comprehensive REST API following OpenAPI 3.0 specification:
| Category | Endpoints | Description |
|---|---|---|
| Auth | 4 endpoints | Register, login, refresh, user info |
| Workbooks | 8 endpoints | CRUD, upload, sheets, data |
| Calculations | 7 endpoints | Evaluate, batch, validate, recalculate |
| Compliance | 5 endpoints | Run tests, results, history |
| Scenarios | 6 endpoints | Create, trades, analyze, export |
Authentication Options¶
| Method | Use Case | Token Lifetime |
|---|---|---|
| JWT (Bearer) | User-facing apps | 15 minutes (access) |
| API Key | Service integrations | Up to 1 year |
| Refresh Token | Session management | 7 days |
Webhooks¶
Event-driven notifications:
- Workbook upload complete
- Compliance test finished
- Scenario analysis ready
- Threshold breach detected
Batch Operations¶
High-volume processing support:
- Multi-formula evaluation
- Bulk data updates
- Parallel processing
- Rate limit optimization
Step-by-Step Tutorials¶
Authentication Flow¶
Learn the complete authentication flow for CalcBridge.
Option 1: JWT Authentication (User Apps)¶
sequenceDiagram
participant App
participant CalcBridge
participant User
App->>User: Show login form
User->>App: Enter credentials
App->>CalcBridge: POST /auth/login
CalcBridge->>App: access_token + refresh_token
App->>App: Store tokens securely
App->>CalcBridge: GET /workbooks (Bearer token)
CalcBridge->>App: 200 OK + data Step 1: Register (if new user)
curl -X POST https://api.calcbridge.io/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "developer@example.com",
"password": "SecureP@ssw0rd!",
"full_name": "Dev User",
"organization_name": "Dev Corp"
}'
Response:
{
"id": "usr_abc123",
"email": "developer@example.com",
"tenant_id": "tenant_xyz789",
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOi...",
"refresh_token": "rt_aBcDeFgHiJkLmNoPqRsTuVwXyZ...",
"token_type": "bearer",
"expires_in": 900
}
Step 2: Login (existing user)
curl -X POST https://api.calcbridge.io/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"username": "developer@example.com",
"password": "SecureP@ssw0rd!"
}'
Step 3: Use Access Token
curl -X GET https://api.calcbridge.io/api/v1/workbooks \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOi..."
Step 4: Refresh When Expired
curl -X POST https://api.calcbridge.io/api/v1/auth/refresh \
-H "Content-Type: application/json" \
-d '{
"refresh_token": "rt_aBcDeFgHiJkLmNoPqRsTuVwXyZ..."
}'
Option 2: API Key Authentication (Services)¶
# Use X-API-Key header
curl -X GET https://api.calcbridge.io/api/v1/workbooks \
-H "X-API-Key: cb_sk_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ0123456789"
Best Practice
Use JWT for user-facing applications where users log in. Use API keys for backend services and automated scripts.
Uploading Workbooks via API¶
Programmatically upload Excel files to CalcBridge.
Basic Upload¶
curl -X POST https://api.calcbridge.io/api/v1/workbooks/upload \
-H "Authorization: Bearer $TOKEN" \
-F "file=@portfolio_data.xlsx" \
-F "name=Q1 2024 Holdings"
Response:
{
"id": "wb_abc123",
"name": "Q1 2024 Holdings",
"status": "processing",
"file_name": "portfolio_data.xlsx",
"file_size": 2456789,
"created_at": "2024-01-15T10:30:00Z",
"sheets": []
}
Upload with Mapping Profile¶
curl -X POST https://api.calcbridge.io/api/v1/workbooks/upload \
-H "Authorization: Bearer $TOKEN" \
-F "file=@servicer_report.xlsx" \
-F "name=January Servicer Report" \
-F "mapping_profile=servicer_xyz_monthly" \
-F "validate=true"
Python Example¶
import requests
def upload_workbook(file_path: str, name: str, token: str) -> dict:
"""Upload an Excel workbook to CalcBridge."""
url = "https://api.calcbridge.io/api/v1/workbooks/upload"
headers = {
"Authorization": f"Bearer {token}"
}
with open(file_path, "rb") as f:
files = {
"file": (file_path, f, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
}
data = {
"name": name
}
response = requests.post(url, headers=headers, files=files, data=data)
response.raise_for_status()
return response.json()
# Usage
result = upload_workbook("portfolio.xlsx", "Q1 Holdings", access_token)
print(f"Workbook ID: {result['id']}")
TypeScript/Node.js Example¶
import FormData from 'form-data';
import fs from 'fs';
import axios from 'axios';
async function uploadWorkbook(
filePath: string,
name: string,
token: string
): Promise<Workbook> {
const form = new FormData();
form.append('file', fs.createReadStream(filePath));
form.append('name', name);
const response = await axios.post(
'https://api.calcbridge.io/api/v1/workbooks/upload',
form,
{
headers: {
Authorization: `Bearer ${token}`,
...form.getHeaders(),
},
}
);
return response.data;
}
// Usage
const result = await uploadWorkbook('portfolio.xlsx', 'Q1 Holdings', accessToken);
console.log(`Workbook ID: ${result.id}`);
Polling for Completion¶
import time
def wait_for_processing(workbook_id: str, token: str, timeout: int = 300) -> dict:
"""Wait for workbook processing to complete."""
url = f"https://api.calcbridge.io/api/v1/workbooks/{workbook_id}"
headers = {"Authorization": f"Bearer {token}"}
start_time = time.time()
while time.time() - start_time < timeout:
response = requests.get(url, headers=headers)
workbook = response.json()
if workbook["status"] == "ready":
return workbook
elif workbook["status"] == "failed":
raise Exception(f"Processing failed: {workbook.get('error')}")
time.sleep(2) # Poll every 2 seconds
raise TimeoutError("Workbook processing timed out")
Evaluating Formulas Programmatically¶
Execute Excel formulas through the API.
Single Formula Evaluation¶
curl -X POST https://api.calcbridge.io/api/v1/calculations/evaluate \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"formula": "=SUM(100, 200, 300)",
"context": {}
}'
Response:
Formula with Cell References¶
curl -X POST https://api.calcbridge.io/api/v1/calculations/evaluate \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"formula": "=IF(A1>100, B1*1.1, B1*1.05)",
"context": {
"A1": 150,
"B1": 1000
}
}'
Response:
Batch Formula Evaluation¶
curl -X POST https://api.calcbridge.io/api/v1/calculations/batch \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"formulas": [
{"id": "calc1", "formula": "=SUM(A1:A10)", "context": {"A1": 1, "A2": 2, "A3": 3}},
{"id": "calc2", "formula": "=AVERAGE(B1:B5)", "context": {"B1": 10, "B2": 20, "B3": 30}},
{"id": "calc3", "formula": "=VLOOKUP(\"A\", C1:D3, 2, FALSE)", "context": {
"C1": "A", "D1": 100,
"C2": "B", "D2": 200,
"C3": "C", "D3": 300
}}
]
}'
Response:
{
"results": [
{"id": "calc1", "result": 6, "result_type": "number"},
{"id": "calc2", "result": 20, "result_type": "number"},
{"id": "calc3", "result": 100, "result_type": "number"}
],
"total_execution_time_ms": 15,
"successful": 3,
"failed": 0
}
Python Calculation Client¶
class CalcBridgeClient:
"""Python client for CalcBridge calculations."""
def __init__(self, api_key: str, base_url: str = "https://api.calcbridge.io"):
self.api_key = api_key
self.base_url = base_url
self.session = requests.Session()
self.session.headers["X-API-Key"] = api_key
def evaluate(self, formula: str, context: dict = None) -> any:
"""Evaluate a single formula."""
response = self.session.post(
f"{self.base_url}/api/v1/calculations/evaluate",
json={"formula": formula, "context": context or {}}
)
response.raise_for_status()
return response.json()["result"]
def evaluate_batch(self, formulas: list) -> list:
"""Evaluate multiple formulas."""
response = self.session.post(
f"{self.base_url}/api/v1/calculations/batch",
json={"formulas": formulas}
)
response.raise_for_status()
return response.json()["results"]
def validate(self, formula: str) -> dict:
"""Validate formula syntax."""
response = self.session.post(
f"{self.base_url}/api/v1/calculations/validate",
json={"formula": formula}
)
response.raise_for_status()
return response.json()
# Usage
client = CalcBridgeClient(api_key="cb_sk_live_...")
result = client.evaluate("=SUMIFS(A:A, B:B, \">100\")", {"A1": 50, "B1": 150, "A2": 100, "B2": 50})
print(f"Result: {result}")
Building a Custom Dashboard¶
Create a custom compliance dashboard using the CalcBridge API.
Dashboard Architecture¶
flowchart LR
subgraph Frontend["Custom Dashboard"]
A[React/Vue/Angular]
B[Charts Library]
end
subgraph API["CalcBridge API"]
C[Workbooks]
D[Compliance]
E[Scenarios]
end
subgraph Data["Your Backend"]
F[Cache Layer]
G[Aggregation]
end
A --> F
F --> C
F --> D
F --> E
B --> A
style Frontend fill:#DBEAFE,stroke:#3B82F6
style API fill:#DCFCE7,stroke:#22C55E
style Data fill:#FEF3C7,stroke:#F59E0B React Dashboard Example¶
// components/ComplianceDashboard.tsx
import { useEffect, useState } from 'react';
import { CalcBridgeClient } from '../lib/calcbridge';
interface ComplianceResult {
test_name: string;
status: 'pass' | 'fail' | 'warning';
current_value: number;
threshold: number;
cushion: number;
}
export function ComplianceDashboard({ workbookId }: { workbookId: string }) {
const [results, setResults] = useState<ComplianceResult[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function fetchCompliance() {
const client = new CalcBridgeClient(process.env.CALCBRIDGE_API_KEY!);
// Run compliance tests
const runResult = await client.runComplianceTests(workbookId, 'standard');
// Get results
const testResults = await client.getComplianceResults(runResult.run_id);
setResults(testResults.tests);
setLoading(false);
}
fetchCompliance();
}, [workbookId]);
if (loading) return <div>Loading...</div>;
return (
<div className="compliance-dashboard">
<h2>Compliance Status</h2>
<div className="summary-cards">
<SummaryCard
title="Passing"
value={results.filter(r => r.status === 'pass').length}
color="green"
/>
<SummaryCard
title="Warnings"
value={results.filter(r => r.status === 'warning').length}
color="yellow"
/>
<SummaryCard
title="Failing"
value={results.filter(r => r.status === 'fail').length}
color="red"
/>
</div>
<div className="test-results">
{results.map(result => (
<TestResultRow key={result.test_name} result={result} />
))}
</div>
</div>
);
}
Backend Caching Layer¶
# backend/services/compliance_service.py
from functools import lru_cache
import redis
from calcbridge import CalcBridgeClient
class ComplianceService:
def __init__(self):
self.client = CalcBridgeClient(api_key=os.environ["CALCBRIDGE_API_KEY"])
self.redis = redis.Redis(host="localhost", port=6379)
def get_compliance_summary(self, workbook_id: str) -> dict:
"""Get compliance summary with caching."""
cache_key = f"compliance:{workbook_id}"
# Check cache
cached = self.redis.get(cache_key)
if cached:
return json.loads(cached)
# Fetch from API
run = self.client.run_compliance_tests(workbook_id, "standard")
results = self.client.get_compliance_results(run["run_id"])
summary = {
"total": len(results["tests"]),
"passing": len([t for t in results["tests"] if t["status"] == "pass"]),
"warnings": len([t for t in results["tests"] if t["status"] == "warning"]),
"failing": len([t for t in results["tests"] if t["status"] == "fail"]),
"tests": results["tests"],
"last_updated": datetime.utcnow().isoformat()
}
# Cache for 5 minutes
self.redis.setex(cache_key, 300, json.dumps(summary))
return summary
Tips and Best Practices¶
Error Handling¶
Always Handle Errors
CalcBridge returns standard HTTP status codes. Handle these appropriately:
400: Bad request (check your input)401: Unauthorized (refresh your token)403: Forbidden (check permissions)404: Not found (resource doesn't exist)429: Rate limited (back off and retry)500: Server error (retry with backoff)
def make_api_request(url: str, method: str = "GET", **kwargs) -> dict:
"""Make API request with proper error handling."""
try:
response = requests.request(method, url, **kwargs)
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
if e.response.status_code == 401:
# Token expired, refresh and retry
refresh_token()
return make_api_request(url, method, **kwargs)
elif e.response.status_code == 429:
# Rate limited, wait and retry
retry_after = int(e.response.headers.get("Retry-After", 60))
time.sleep(retry_after)
return make_api_request(url, method, **kwargs)
else:
raise
Rate Limiting¶
| Tier | Requests/Minute | Requests/Hour | Batch Size |
|---|---|---|---|
| Free | 20 | 200 | 10 |
| Standard | 100 | 3,000 | 50 |
| Premium | 500 | 15,000 | 100 |
| Enterprise | Custom | Custom | Custom |
Performance Tips¶
- Use batch endpoints for multiple operations
- Implement caching for frequently accessed data
- Use compression for large payloads
- Paginate large result sets
- Use webhooks instead of polling
Security Checklist¶
- Store API keys in environment variables or secrets manager
- Use HTTPS for all API calls
- Implement token refresh before expiration
- Validate webhook signatures
- Log API calls for debugging (mask sensitive data)
Quick Reference¶
API Base URLs¶
| Environment | URL |
|---|---|
| Production | https://api.calcbridge.io |
| Sandbox | https://sandbox.calcbridge.io |
| Local Dev | http://localhost:8000 |
Common Endpoints¶
# Authentication
POST /api/v1/auth/register
POST /api/v1/auth/login
POST /api/v1/auth/refresh
GET /api/v1/auth/me
# Workbooks
GET /api/v1/workbooks
POST /api/v1/workbooks/upload
GET /api/v1/workbooks/{id}
GET /api/v1/workbooks/{id}/sheets
GET /api/v1/workbooks/{id}/sheets/{name}/data
# Calculations
POST /api/v1/calculations/evaluate
POST /api/v1/calculations/batch
POST /api/v1/calculations/validate
GET /api/v1/calculations/functions
# Compliance
POST /api/v1/compliance/run
GET /api/v1/compliance/results/{run_id}
# Scenarios
POST /api/v1/scenarios
POST /api/v1/scenarios/{id}/trades
POST /api/v1/scenarios/{id}/analyze
Response Codes¶
| Code | Meaning | Action |
|---|---|---|
| 200 | Success | Process response |
| 201 | Created | Resource created |
| 202 | Accepted | Async processing started |
| 400 | Bad Request | Fix input |
| 401 | Unauthorized | Authenticate |
| 403 | Forbidden | Check permissions |
| 404 | Not Found | Check resource ID |
| 429 | Rate Limited | Wait and retry |
| 500 | Server Error | Retry with backoff |
Next Steps¶
- Complete this guide
- Set up authentication
- Upload your first workbook via API
- Evaluate formulas programmatically
- Build a custom integration