Version: 1.0
Last Updated: March 10, 2026
Languages: Bash (curl), Python, JavaScript
- Authentication Examples
- Risks CRUD
- Mitigations Management
- Assets
- Statistics & Dashboard
- Advanced Features
curl -X POST https://api.openrisk.io/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "secure_password"
}' | jq .import requests
import json
response = requests.post(
'https://api.openrisk.io/api/v1/auth/login',
json={
'email': 'user@example.com',
'password': 'secure_password'
}
)
data = response.json()
access_token = data['access_token']
print(f"Token: {access_token}")const axios = require('axios');
const response = await axios.post('https://api.openrisk.io/api/v1/auth/login', {
email: 'user@example.com',
password: 'secure_password'
});
const accessToken = response.data.access_token;
console.log(`Token: ${accessToken}`);const response = await fetch('https://api.openrisk.io/api/v1/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: 'user@example.com',
password: 'secure_password'
})
});
const data = await response.json();
const accessToken = data.access_token;
console.log(`Token: ${accessToken}`);
// Store in localStorage for later use
localStorage.setItem('openrisk_token', accessToken);curl -X POST https://api.openrisk.io/api/v1/auth/refresh \
-H "Content-Type: application/json" \
-d '{
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}' | jq .response = requests.post(
'https://api.openrisk.io/api/v1/auth/refresh',
json={'refresh_token': refresh_token}
)
new_token = response.json()['access_token']TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
curl https://api.openrisk.io/api/v1/users/me \
-H "Authorization: Bearer $TOKEN" | jq .headers = {'Authorization': f'Bearer {access_token}'}
response = requests.get(
'https://api.openrisk.io/api/v1/users/me',
headers=headers
)
user = response.json()
print(f"User: {user['email']}, Role: {user['role']}")const response = await fetch('https://api.openrisk.io/api/v1/users/me', {
headers: {
'Authorization': `Bearer ${accessToken}`
}
});
const user = await response.json();
console.log(`User: ${user.email}, Role: ${user.role}`);TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
# Simple list
curl https://api.openrisk.io/api/v1/risks \
-H "Authorization: Bearer $TOKEN" | jq .
# With pagination
curl 'https://api.openrisk.io/api/v1/risks?page=1&limit=10' \
-H "Authorization: Bearer $TOKEN" | jq .
# With sorting
curl 'https://api.openrisk.io/api/v1/risks?sort_by=-created_at' \
-H "Authorization: Bearer $TOKEN" | jq .import requests
headers = {'Authorization': f'Bearer {access_token}'}
# Simple list
response = requests.get(
'https://api.openrisk.io/api/v1/risks',
headers=headers
)
risks = response.json()
print(f"Found {len(risks)} risks")
# With pagination
response = requests.get(
'https://api.openrisk.io/api/v1/risks',
headers=headers,
params={'page': 1, 'limit': 10}
)
# With sorting
response = requests.get(
'https://api.openrisk.io/api/v1/risks',
headers=headers,
params={'sort_by': '-created_at'}
)const token = localStorage.getItem('openrisk_token');
// Simple list
const response = await fetch('https://api.openrisk.io/api/v1/risks', {
headers: { 'Authorization': `Bearer ${token}` }
});
const risks = await response.json();
// With pagination
const response = await fetch(
'https://api.openrisk.io/api/v1/risks?page=1&limit=10',
{ headers: { 'Authorization': `Bearer ${token}` } }
);
// With sorting
const response = await fetch(
'https://api.openrisk.io/api/v1/risks?sort_by=-created_at',
{ headers: { 'Authorization': `Bearer ${token}` } }
);curl -X POST https://api.openrisk.io/api/v1/risks \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Unpatched Server Vulnerability",
"description": "Critical security patch not applied to production server",
"impact": 5,
"probability": 4,
"tags": ["production", "infrastructure", "critical"],
"asset_ids": ["550e8400-e29b-41d4-a716-446655440000"],
"frameworks": ["ISO_27001", "CIS"]
}' | jq .risk_data = {
"title": "Unpatched Server Vulnerability",
"description": "Critical security patch not applied to production server",
"impact": 5,
"probability": 4,
"tags": ["production", "infrastructure", "critical"],
"asset_ids": ["550e8400-e29b-41d4-a716-446655440000"],
"frameworks": ["ISO_27001", "CIS"]
}
response = requests.post(
'https://api.openrisk.io/api/v1/risks',
json=risk_data,
headers={'Authorization': f'Bearer {access_token}'}
)
risk = response.json()
print(f"Created risk: {risk['id']}")const riskData = {
title: "Unpatched Server Vulnerability",
description: "Critical security patch not applied",
impact: 5,
probability: 4,
tags: ["production", "infrastructure", "critical"],
asset_ids: ["550e8400-e29b-41d4-a716-446655440000"],
frameworks: ["ISO_27001", "CIS"]
};
const response = await fetch('https://api.openrisk.io/api/v1/risks', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(riskData)
});
const risk = await response.json();
console.log(`Created risk: ${risk.id}`);RISK_ID="550e8400-e29b-41d4-a716-446655440001"
curl https://api.openrisk.io/api/v1/risks/$RISK_ID \
-H "Authorization: Bearer $TOKEN" | jq .risk_id = "550e8400-e29b-41d4-a716-446655440001"
response = requests.get(
f'https://api.openrisk.io/api/v1/risks/{risk_id}',
headers={'Authorization': f'Bearer {access_token}'}
)
risk = response.json()
print(f"Risk: {risk['title']}, Status: {risk['status']}")curl -X PATCH https://api.openrisk.io/api/v1/risks/$RISK_ID \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Updated Title",
"status": "open",
"probability": 3
}' | jq .update_data = {
"title": "Updated Title",
"status": "open",
"probability": 3
}
response = requests.patch(
f'https://api.openrisk.io/api/v1/risks/{risk_id}',
json=update_data,
headers={'Authorization': f'Bearer {access_token}'}
)curl -X DELETE https://api.openrisk.io/api/v1/risks/$RISK_ID \
-H "Authorization: Bearer $TOKEN"response = requests.delete(
f'https://api.openrisk.io/api/v1/risks/{risk_id}',
headers={'Authorization': f'Bearer {access_token}'}
)
if response.status_code == 204:
print("Risk deleted successfully")RISK_ID="550e8400-e29b-41d4-a716-446655440001"
curl -X POST https://api.openrisk.io/api/v1/risks/$RISK_ID/mitigations \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Apply security patch",
"assignee": "alice@example.com",
"due_date": "2026-03-31T23:59:59Z",
"cost": 2,
"mitigation_time": 4
}' | jq .mitigation_data = {
"title": "Apply security patch",
"assignee": "alice@example.com",
"due_date": "2026-03-31T23:59:59Z",
"cost": 2,
"mitigation_time": 4
}
response = requests.post(
f'https://api.openrisk.io/api/v1/risks/{risk_id}/mitigations',
json=mitigation_data,
headers={'Authorization': f'Bearer {access_token}'}
)
mitigation = response.json()
print(f"Created mitigation: {mitigation['id']}")MITIGATION_ID="660f9511-f40d-52e5-b827-557766551002"
curl -X PATCH https://api.openrisk.io/api/v1/mitigations/$MITIGATION_ID \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Updated mitigation title",
"progress": 75,
"status": "IN_PROGRESS"
}' | jq .update_data = {
"title": "Updated mitigation title",
"progress": 75,
"status": "IN_PROGRESS"
}
response = requests.patch(
f'https://api.openrisk.io/api/v1/mitigations/{mitigation_id}',
json=update_data,
headers={'Authorization': f'Bearer {access_token}'}
)curl -X PATCH https://api.openrisk.io/api/v1/mitigations/$MITIGATION_ID/toggle \
-H "Authorization: Bearer $TOKEN"response = requests.patch(
f'https://api.openrisk.io/api/v1/mitigations/{mitigation_id}/toggle',
headers={'Authorization': f'Bearer {access_token}'}
)curl -X POST https://api.openrisk.io/api/v1/mitigations/$MITIGATION_ID/subactions \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Download and test patch"
}' | jq .response = requests.post(
f'https://api.openrisk.io/api/v1/mitigations/{mitigation_id}/subactions',
json={"title": "Download and test patch"},
headers={'Authorization': f'Bearer {access_token}'}
)
subaction = response.json()
print(f"Created sub-action: {subaction['id']}")SUBACTION_ID="770g0622-g51e-63f6-c938-668877662003"
curl -X PATCH https://api.openrisk.io/api/v1/mitigations/$MITIGATION_ID/subactions/$SUBACTION_ID/toggle \
-H "Authorization: Bearer $TOKEN"curl https://api.openrisk.io/api/v1/assets \
-H "Authorization: Bearer $TOKEN" | jq .response = requests.get(
'https://api.openrisk.io/api/v1/assets',
headers={'Authorization': f'Bearer {access_token}'}
)
assets = response.json()
for asset in assets:
print(f"Asset: {asset['name']} ({asset['type']})")curl -X POST https://api.openrisk.io/api/v1/assets \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Production Database",
"type": "database",
"description": "Primary PostgreSQL database",
"location": "AWS us-east-1",
"owner": "database-team@example.com"
}' | jq .asset_data = {
"name": "Production Database",
"type": "database",
"description": "Primary PostgreSQL database",
"location": "AWS us-east-1",
"owner": "database-team@example.com"
}
response = requests.post(
'https://api.openrisk.io/api/v1/assets',
json=asset_data,
headers={'Authorization': f'Bearer {access_token}'}
)
asset = response.json()
print(f"Created asset: {asset['id']}")curl https://api.openrisk.io/api/v1/stats \
-H "Authorization: Bearer $TOKEN" | jq .Response:
{
"total_risks": 45,
"open_risks": 12,
"high_severity_risks": 3,
"critical_severity_risks": 1,
"mitigated_risks": 20,
"pending_mitigations": 8,
"average_risk_score": 3.2
}curl https://api.openrisk.io/api/v1/stats/risk-matrix \
-H "Authorization: Bearer $TOKEN" | jq .Response:
{
"matrix": [
[0, 2, 5, 3, 1],
[1, 4, 8, 6, 2],
[2, 6, 12, 9, 4],
[1, 5, 10, 8, 3],
[0, 2, 4, 3, 1]
],
"total_risks": 45
}curl https://api.openrisk.io/api/v1/stats/trends \
-H "Authorization: Bearer $TOKEN" | jq .Response:
{
"trends": [
{ "date": "2026-02-10", "total": 40, "open": 10, "closed": 30 },
{ "date": "2026-02-17", "total": 42, "open": 11, "closed": 31 },
{ "date": "2026-02-24", "total": 44, "open": 12, "closed": 32 },
{ "date": "2026-03-03", "total": 45, "open": 12, "closed": 33 },
{ "date": "2026-03-10", "total": 45, "open": 12, "closed": 33 }
]
}curl https://api.openrisk.io/api/v1/dashboard/complete \
-H "Authorization: Bearer $TOKEN" | jq .curl https://api.openrisk.io/api/v1/export/pdf \
-H "Authorization: Bearer $TOKEN" \
-o risks_report.pdfresponse = requests.get(
'https://api.openrisk.io/api/v1/export/pdf',
headers={'Authorization': f'Bearer {access_token}'}
)
with open('risks_report.pdf', 'wb') as f:
f.write(response.content)curl https://api.openrisk.io/api/v1/mitigations/recommended \
-H "Authorization: Bearer $TOKEN" | jq .Response:
[
{
"risk_id": "550e8400-e29b-41d4-a716-446655440001",
"risk_title": "Unpatched Server",
"mitigation": "Apply latest security patch",
"effort_days": 2,
"cost": 2,
"spp_score": 0.95
},
{
"risk_id": "550e8400-e29b-41d4-a716-446655440002",
"risk_title": "Weak Passwords",
"mitigation": "Enforce strong password policy",
"effort_days": 5,
"cost": 2,
"spp_score": 0.87
}
]curl https://api.openrisk.io/api/v1/gamification/me \
-H "Authorization: Bearer $TOKEN" | jq .Response:
{
"user_id": "550e8400-e29b-41d4-a716-446655440000",
"level": 5,
"points": 2850,
"badges": ["First Risk", "Risk Analyst", "Mitigation Master"],
"streak": 12,
"rank": "Expert"
}import requests
def make_api_call(method, endpoint, data=None):
url = f'https://api.openrisk.io/api/v1{endpoint}'
headers = {'Authorization': f'Bearer {access_token}'}
try:
if method == 'GET':
response = requests.get(url, headers=headers)
elif method == 'POST':
response = requests.post(url, json=data, headers=headers)
elif method == 'PATCH':
response = requests.patch(url, json=data, headers=headers)
# Check for errors
if response.status_code == 401:
print("Error: Unauthorized - token may be expired")
# Refresh token
refresh_token()
return make_api_call(method, endpoint, data)
elif response.status_code == 403:
print("Error: Forbidden - insufficient permissions")
return None
elif response.status_code == 429:
print("Error: Rate limited - wait before retrying")
return None
elif response.status_code == 400:
error = response.json()
print(f"Error: {error.get('error')}")
print(f"Details: {error.get('details')}")
return None
elif response.status_code >= 500:
print("Error: Server error - try again later")
return None
return response.json()
except requests.exceptions.RequestException as e:
print(f"Network error: {e}")
return Noneasync function makeApiCall(method, endpoint, data = null) {
const url = `https://api.openrisk.io/api/v1${endpoint}`;
const headers = {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
};
try {
const response = await fetch(url, {
method,
headers,
body: data ? JSON.stringify(data) : null
});
if (response.status === 401) {
console.error('Unauthorized - token expired');
await refreshToken();
return makeApiCall(method, endpoint, data);
} else if (response.status === 403) {
console.error('Forbidden - insufficient permissions');
return null;
} else if (response.status === 429) {
console.error('Rate limited - wait before retrying');
return null;
} else if (response.status === 400) {
const error = await response.json();
console.error(`Validation error: ${error.error}`);
console.error(`Details: ${error.details}`);
return null;
} else if (response.status >= 500) {
console.error('Server error - try again later');
return null;
}
return response.json();
} catch (error) {
console.error(`Network error: ${error.message}`);
return null;
}
}- Always validate responses - Check status codes and error messages
- Implement retry logic - Use exponential backoff for failed requests
- Cache tokens - Store tokens securely for reuse
- Set request timeouts - Prevent hanging requests
- Log API calls - For debugging and audit purposes
- Handle rate limits - Implement backoff and queue logic
- Sanitize inputs - Validate all user inputs before sending
- Use pagination - For large datasets, use page/limit parameters
Questions? See API_REFERENCE.md or API_SECURITY_GUIDE.md