Skip to main content

Real-World Examples

The API workflows feature enables powerful system integration scenarios. Here are practical examples of how organizations use this feature:

1. HR System Integration

Scenario: Your company uses SAP HR system and wants employee data to flow into OSPROV approval workflows automatically.

Setup:

  • Create API User: "SAP-HR-Integration"
  • Workflow: "Employee Onboarding Approval"
  • Integration: SAP pushes new employee data via API when hired

API Request

{
"employee_name": "Jane Smith",
"employee_id": "EMP001234",
"department": "Engineering",
"start_date": "2024-02-01",
"salary": 85000,
"manager_email": "john.manager@company.com",
"position": "Senior Developer",
"employment_type": "full_time",
"benefits": {
"health_insurance": true,
"dental_insurance": true,
"vision_insurance": false,
"retirement_plan": true
},
"emergency_contacts": [
{
"name": "John Smith",
"relationship": "spouse",
"phone": "+1234567890"
}
]
}

Implementation Example (Node.js)

const axios = require('axios');

class HRIntegration {
constructor(apiToken, baseUrl) {
this.apiToken = apiToken;
this.baseUrl = baseUrl;
this.workflowId = 123; // Employee onboarding workflow
}

async submitNewEmployee(employeeData) {
try {
const response = await axios.post(
`${this.baseUrl}/api/submissions/workflow/${this.workflowId}`,
employeeData,
{
headers: {
'Authorization': `Bearer ${this.apiToken}`,
'Content-Type': 'application/json'
}
}
);

console.log(`Employee onboarding submitted: ${response.data.submission.id}`);
return response.data;
} catch (error) {
console.error('HR Integration Error:', error.response?.data || error.message);
throw error;
}
}
}

// Usage
const hrIntegration = new HRIntegration(
process.env.OSPROV_HR_API_TOKEN,
'https://your-osprov-domain.com'
);

// When new employee is hired in SAP
hrIntegration.submitNewEmployee(newEmployeeData);

Result: Automatic approval workflow triggered, manager gets notification, HR processes continue seamlessly without manual data entry.

2. Procurement System Integration

Scenario: Your ERP system (Oracle/SAP) needs purchase orders above $10K to go through OSPROV approval workflow.

Setup:

  • API User: "ERP-Procurement-Bot"
  • Workflow: "Purchase Order Approval"
  • Trigger: ERP detects PO > $10K threshold

API Request

{
"po_number": "PO-2024-001567",
"vendor_name": "Tech Supplies Inc",
"total_amount": 25000,
"department": "IT",
"requested_by": "alice@company.com",
"urgency": "standard",
"delivery_date": "2024-03-15",
"budget_code": "IT-2024-Q1",
"items": [
{
"description": "Laptops",
"quantity": 10,
"unit_price": 2500,
"total_price": 25000,
"category": "hardware",
"vendor_part_number": "LAP-001"
}
],
"justification": "Replacement laptops for new engineering team members",
"approver_suggestions": [
"finance.manager@company.com",
"it.director@company.com"
]
}

Implementation Example (Python)

import requests
import os
from datetime import datetime

class ProcurementIntegration:
def __init__(self):
self.api_token = os.getenv('OSPROV_PROCUREMENT_API_TOKEN')
self.base_url = 'https://your-osprov-domain.com'
self.workflow_id = 456 # Purchase order approval workflow

def submit_purchase_order(self, po_data):
headers = {
'Authorization': f'Bearer {self.api_token}',
'Content-Type': 'application/json'
}

try:
response = requests.post(
f'{self.base_url}/api/submissions/workflow/{self.workflow_id}',
json=po_data,
headers=headers
)
response.raise_for_status()

submission = response.json()
print(f"PO approval submitted: {submission['submission']['id']}")
return submission

except requests.exceptions.RequestException as e:
print(f"Procurement integration error: {e}")
if hasattr(e, 'response') and e.response is not None:
print(f"Error details: {e.response.text}")
raise

def check_po_threshold(self, po_amount, threshold=10000):
return po_amount >= threshold

# Usage in ERP system
procurement = ProcurementIntegration()

# When PO is created in ERP
if procurement.check_po_threshold(po_data['total_amount']):
procurement.submit_purchase_order(po_data)

Result: Approval workflow starts automatically, finance team gets notified, procurement continues after approval with full audit trail.

3. Mobile App Field Submissions

Scenario: Field workers use mobile app to submit inspection reports that need manager approval.

Setup:

  • API User: "FieldWorker-Mobile-App"
  • Workflow: "Equipment Inspection Approval"
  • App: Mobile app submits inspection data with photos

API Request

{
"inspector_name": "Mike Johnson",
"inspector_id": "INSP-001",
"equipment_id": "PUMP-A-001",
"equipment_location": "Building A, Floor 2, Room 205",
"inspection_date": "2024-01-15",
"inspection_type": "routine_maintenance",
"status": "needs_repair",
"findings": "Bearing vibration detected, oil leak observed at connection point",
"photos": [
"inspection_001.jpg",
"inspection_002.jpg",
"oil_leak_detail.jpg"
],
"priority": "high",
"estimated_repair_cost": 2500,
"recommended_action": "Replace bearing assembly and reseal connections",
"safety_concerns": true,
"safety_notes": "Equipment should be taken offline until repairs completed",
"next_inspection_due": "2024-02-15",
"inspector_signature": "digital_signature_hash",
"gps_coordinates": {
"latitude": 40.7128,
"longitude": -74.0060
}
}

Implementation Example (React Native)

import AsyncStorage from '@react-native-async-storage/async-storage';

class FieldInspectionAPI {
constructor() {
this.baseUrl = 'https://your-osprov-domain.com';
this.workflowId = 789; // Equipment inspection workflow
}

async getApiToken() {
return await AsyncStorage.getItem('osprov_api_token');
}

async submitInspection(inspectionData) {
const apiToken = await this.getApiToken();

try {
const response = await fetch(
`${this.baseUrl}/api/submissions/workflow/${this.workflowId}`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${apiToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(inspectionData)
}
);

if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.error || 'Submission failed');
}

const result = await response.json();

// Store submission ID for tracking
await AsyncStorage.setItem(
`inspection_${inspectionData.equipment_id}`,
result.submission.id.toString()
);

return result;
} catch (error) {
console.error('Inspection submission error:', error);
throw error;
}
}

async submitOfflineInspections() {
const offlineInspections = await AsyncStorage.getItem('offline_inspections');

if (offlineInspections) {
const inspections = JSON.parse(offlineInspections);

for (const inspection of inspections) {
try {
await this.submitInspection(inspection);
console.log(`Offline inspection submitted: ${inspection.equipment_id}`);
} catch (error) {
console.error(`Failed to submit offline inspection: ${error.message}`);
}
}

// Clear offline storage after successful submission
await AsyncStorage.removeItem('offline_inspections');
}
}
}

// Usage in mobile app
const inspectionAPI = new FieldInspectionAPI();

// Submit inspection when online
inspectionAPI.submitInspection(inspectionData)
.then(result => {
showSuccessMessage('Inspection submitted successfully');
})
.catch(error => {
showErrorMessage('Failed to submit inspection');
});

Result: Maintenance manager gets approval request with photos, can approve repairs immediately from mobile device.

4. Customer Portal Integration

Scenario: External customers submit service requests through your customer portal, which need internal approval before processing.

Setup:

  • API User: "Customer-Portal-API"
  • Workflow: "Service Request Approval"
  • Portal: Customer portal sends requests to OSPROV for internal approval

API Request

{
"customer_name": "ABC Manufacturing",
"customer_id": "CUST-5678",
"contact_person": "Sarah Johnson",
"contact_email": "sarah@abcmanufacturing.com",
"contact_phone": "+1-555-0123",
"service_type": "equipment_maintenance",
"urgency": "critical",
"description": "Production line conveyor belt malfunction causing downtime",
"preferred_date": "2024-01-20",
"preferred_time": "08:00",
"site_location": "Plant A - Line 2",
"equipment_details": {
"manufacturer": "ConveyorTech",
"model": "CT-2000",
"serial_number": "CT2000-001234",
"installation_date": "2020-03-15"
},
"problem_symptoms": [
"unusual_noise",
"belt_slipping",
"reduced_speed"
],
"business_impact": "High - Production line stopped, affecting daily output",
"estimated_downtime": "4 hours",
"attachments": [
"error_log.pdf",
"equipment_photo.jpg"
],
"service_history": {
"last_service_date": "2023-12-01",
"service_frequency": "quarterly"
}
}

Implementation Example (PHP)

<?php
class CustomerPortalIntegration {
private $apiToken;
private $baseUrl;
private $workflowId;

public function __construct() {
$this->apiToken = getenv('OSPROV_PORTAL_API_TOKEN');
$this->baseUrl = 'https://your-osprov-domain.com';
$this->workflowId = 101; // Service request workflow
}

public function submitServiceRequest($requestData) {
$headers = [
'Authorization: Bearer ' . $this->apiToken,
'Content-Type: application/json'
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->baseUrl . '/api/submissions/workflow/' . $this->workflowId);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($requestData));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpCode !== 201) {
$errorData = json_decode($response, true);
throw new Exception('Service request submission failed: ' . $errorData['error']);
}

return json_decode($response, true);
}

public function trackServiceRequest($submissionId) {
// Implementation for tracking request status
// This would typically involve additional API calls
}
}

// Usage in customer portal
try {
$portal = new CustomerPortalIntegration();
$result = $portal->submitServiceRequest($serviceRequestData);

// Store submission ID for customer tracking
$trackingNumber = 'SR-' . $result['submission']['id'];

// Send confirmation email to customer
sendConfirmationEmail($customerEmail, $trackingNumber);

echo json_encode([
'success' => true,
'tracking_number' => $trackingNumber,
'message' => 'Service request submitted successfully'
]);

} catch (Exception $e) {
echo json_encode([
'success' => false,
'error' => $e->getMessage()
]);
}
?>

Result: Service team gets approval request, customer gets tracking number, workflow manages scheduling and resource allocation.

5. IoT Sensor Alerts

Scenario: Temperature sensors in server rooms trigger approval workflows for emergency maintenance when thresholds exceeded.

Setup:

  • API User: "IoT-Monitoring-System"
  • Workflow: "Emergency Maintenance Approval"
  • Sensors: Send alerts when temperature > 75°C

API Request

{
"sensor_id": "TEMP-SENSOR-DC01-R05",
"location": "Data Center 1, Rack 5",
"alert_type": "temperature_threshold_exceeded",
"current_temperature": 78.5,
"threshold_exceeded": 75.0,
"alert_time": "2024-01-15T14:30:00Z",
"severity": "critical",
"trend": "rising",
"rate_of_change": 2.5,
"estimated_time_to_critical": "15 minutes",
"affected_equipment": [
"Server-DC01-R05-01",
"Server-DC01-R05-02",
"Storage-DC01-R05-03"
],
"environmental_data": {
"humidity": 45.2,
"air_pressure": 1013.25,
"air_flow_rate": 850
},
"historical_data": {
"avg_temp_last_hour": 72.1,
"max_temp_last_24h": 74.8,
"last_maintenance": "2024-01-01T09:00:00Z"
},
"recommended_actions": [
"increase_cooling_capacity",
"check_hvac_system",
"inspect_air_filters"
],
"business_impact": "High - Critical servers at risk of overheating",
"estimated_downtime_risk": "2-4 hours if not addressed"
}

Implementation Example (Python IoT)

import requests
import json
import time
from datetime import datetime, timedelta

class IoTMaintenanceIntegration:
def __init__(self):
self.api_token = os.getenv('OSPROV_IOT_API_TOKEN')
self.base_url = 'https://your-osprov-domain.com'
self.workflow_id = 999 # Emergency maintenance workflow
self.temperature_threshold = 75.0
self.alert_cooldown = 300 # 5 minutes between alerts
self.last_alert_time = {}

def check_temperature_alert(self, sensor_data):
sensor_id = sensor_data['sensor_id']
current_temp = sensor_data['current_temperature']

# Check if threshold exceeded
if current_temp <= self.temperature_threshold:
return False

# Check cooldown period
last_alert = self.last_alert_time.get(sensor_id, 0)
if time.time() - last_alert < self.alert_cooldown:
return False

return True

def submit_emergency_alert(self, sensor_data):
if not self.check_temperature_alert(sensor_data):
return None

# Prepare alert data
alert_data = {
**sensor_data,
'alert_time': datetime.utcnow().isoformat() + 'Z',
'threshold_exceeded': self.temperature_threshold,
'severity': self.calculate_severity(sensor_data['current_temperature']),
'estimated_time_to_critical': self.estimate_time_to_critical(sensor_data)
}

try {
response = requests.post(
f'{self.base_url}/api/submissions/workflow/{self.workflow_id}',
json=alert_data,
headers={
'Authorization': f'Bearer {self.api_token}',
'Content-Type': 'application/json'
},
timeout=10
)
response.raise_for_status()

# Update last alert time
self.last_alert_time[sensor_data['sensor_id']] = time.time()

result = response.json()
print(f"Emergency alert submitted: {result['submission']['id']}")
return result

except requests.exceptions.RequestException as e:
print(f"Failed to submit emergency alert: {e}")
# Could implement local alerting as fallback
self.send_local_alert(sensor_data)
raise

def calculate_severity(self, temperature):
if temperature >= 85:
return 'critical'
elif temperature >= 80:
return 'high'
elif temperature >= 75:
return 'medium'
return 'low'

def estimate_time_to_critical(self, sensor_data):
# Simple estimation based on rate of change
current_temp = sensor_data['current_temperature']
rate_of_change = sensor_data.get('rate_of_change', 1.0)
critical_temp = 85.0

if rate_of_change <= 0:
return 'stable'

minutes_to_critical = (critical_temp - current_temp) / rate_of_change
return f"{int(minutes_to_critical)} minutes"

def send_local_alert(self, sensor_data):
# Fallback local alerting when API is unavailable
print(f"LOCAL ALERT: Temperature critical at {sensor_data['location']}")
# Could send email, SMS, or trigger local alarms

# Usage in IoT monitoring system
iot_integration = IoTMaintenanceIntegration()

# Continuous monitoring loop
while True:
sensor_readings = get_all_sensor_data() # Your sensor reading function

for sensor_data in sensor_readings:
try:
iot_integration.submit_emergency_alert(sensor_data)
except Exception as e:
print(f"Alert submission failed for {sensor_data['sensor_id']}: {e}")

time.sleep(60) # Check every minute

Result: Facilities team gets immediate alert, emergency maintenance can be approved and dispatched quickly, preventing equipment damage.

6. Batch Processing Integration

Scenario: Nightly batch job processes multiple applications and submits them for approval.

Implementation Example

import requests
import json
from concurrent.futures import ThreadPoolExecutor, as_completed
import time

class BatchSubmissionProcessor:
def __init__(self):
self.api_token = os.getenv('OSPROV_BATCH_API_TOKEN')
self.base_url = 'https://your-osprov-domain.com'
self.workflow_id = 555
self.max_workers = 5 # Parallel submissions
self.rate_limit_delay = 1 # Seconds between requests

def submit_single_application(self, application_data):
try:
response = requests.post(
f'{self.base_url}/api/submissions/workflow/{self.workflow_id}',
json=application_data,
headers={
'Authorization': f'Bearer {self.api_token}',
'Content-Type': 'application/json'
}
)
response.raise_for_status()
return {
'success': True,
'application_id': application_data['application_id'],
'submission_id': response.json()['submission']['id']
}
except Exception as e:
return {
'success': False,
'application_id': application_data['application_id'],
'error': str(e)
}

def process_batch(self, applications):
results = []

with ThreadPoolExecutor(max_workers=self.max_workers) as executor:
# Submit applications with rate limiting
futures = []
for i, app in enumerate(applications):
if i > 0: # Rate limiting delay
time.sleep(self.rate_limit_delay)

future = executor.submit(self.submit_single_application, app)
futures.append(future)

# Collect results
for future in as_completed(futures):
result = future.result()
results.append(result)

if result['success']:
print(f"✓ Submitted: {result['application_id']}")
else:
print(f"✗ Failed: {result['application_id']} - {result['error']}")

return results

# Usage in batch processing job
batch_processor = BatchSubmissionProcessor()
applications = load_pending_applications() # Your data loading function
results = batch_processor.process_batch(applications)

# Generate batch report
successful = [r for r in results if r['success']]
failed = [r for r in results if not r['success']]

print(f"Batch processing complete: {len(successful)} successful, {len(failed)} failed")

These examples demonstrate the versatility and power of API workflows for automating business processes across different systems and scenarios.