API Documentation
Integrate Swim ProHub 360 analysis into your applications
Quick Start Guide
Get started with the Swim ProHub 360 API. Base URL: http://localhost:5001
1. Check API Health
GET/api/health
curl http://localhost:5001/api/health
2. Upload a Video
POST/api/analyze
curl -X POST \ -F "[email protected]" \ http://localhost:5001/api/analyze
3. Check Job Status
GET/api/jobs/{job_id}/status
curl http://localhost:5001/api/jobs/{job_id}/status
4. Get Analysis Results
GET/api/jobs/{job_id}/result
curl http://localhost:5001/api/jobs/{job_id}/result
5. Chat with AI Coach
POST/api/jobs/{job_id}/chat
curl -X POST \
-H "Content-Type: application/json" \
-d '{"message": "How can I improve?"}' \
http://localhost:5001/api/jobs/{job_id}/chat
6. Compare Two Videos
POST/api/compare
curl -X POST \ -F "[email protected]" \ -F "[email protected]" \ http://localhost:5001/api/compare
Response Metrics Explained
| Metric | Description | Ideal Range |
|---|---|---|
stroke_rate |
Strokes per minute | 40-60 (varies by stroke) |
dps |
Distance per stroke in meters | 1.6-2.2m |
swolf |
SWOLF score (strokes + time for 25m) | Lower is better (30-50) |
speed |
Average speed in meters/minute | 60-100 m/min |
avg_body_angle |
Average body angle deviation | 10-30 degrees |
body_rotation |
Shoulder rotation in degrees | 0-10 degrees |
kick_rhythm |
Kick frequency per minute | Varies by stroke style |
Flutter Integration Guide
Complete guide for integrating the Swim ProHub 360 API into your Flutter application.
1. Add Dependencies
Add these to your pubspec.yaml:
# pubspec.yaml
dependencies:
http: ^1.1.0
http_parser: ^4.0.2
2. Create API Service Class
import 'dart:convert'; import 'dart:io'; import 'package:http/http.dart' as http; class SwimAnalysisService { final String baseUrl; SwimAnalysisService({this.baseUrl = 'http://localhost:5001'}); /// Upload video for analysis Future<String> uploadVideo(File videoFile) async { var request = http.MultipartRequest( 'POST', Uri.parse('$baseUrl/api/analyze'), ); request.files.add(await http.MultipartFile.fromPath( 'video', videoFile.path, )); final response = await request.send(); final body = await response.stream.bytesToString(); if (response.statusCode == 202) { return jsonDecode(body)['job_id']; } throw Exception('Upload failed'); } /// Get job status Future<Map> getJobStatus(String jobId) async { final response = await http.get( Uri.parse('$baseUrl/api/jobs/$jobId/status'), ); return jsonDecode(response.body); } /// Chat with AI coach Future<String> askCoach(String jobId, String message) async { final response = await http.post( Uri.parse('$baseUrl/api/jobs/$jobId/chat'), headers: {'Content-Type': 'application/json'}, body: jsonEncode({'message': message}), ); return jsonDecode(response.body)['response']; } }
3. Example Widget Usage
class VideoAnalysisScreen extends StatefulWidget { @override _VideoAnalysisScreenState createState() => _VideoAnalysisScreenState(); } class _VideoAnalysisScreenState extends State<VideoAnalysisScreen> { final service = SwimAnalysisService(); int progress = 0; Future<void> analyzeVideo(File video) async { final jobId = await service.uploadVideo(video); // Poll for completion while (true) { final status = await service.getJobStatus(jobId); setState(() => progress = status['progress']); if (status['status'] == 'complete') break; await Future.delayed(Duration(seconds: 1)); } } }