API Reference (FastAPI)¶
This page documents the public HTTP API of the SoccerPredictAI inference service. The API contract is the stable interface between clients (UI, batch jobs) and the model.
Source of truth for the complete schema is the generated OpenAPI spec at
/docs(Swagger UI). This page provides the human-oriented contract and examples.
Base URLs¶
- Local:
http://localhost:8000 - Production demo:
https://soccer.dmitryivanov.dev
Authentication¶
All /predict/* endpoints require an X-API-Key header.
/healthcheck/, /metrics, /monitoring/*, and /livescores/ are unauthenticated.
Endpoints¶
GET /healthcheck/¶
Liveness probe for Kubernetes. Checks database connectivity.
Response — 200 OK
{"status": "healthy", "version": "...", "worker_pid": 42, "memory_usage_mb": 210.4, "database": true}
GET /metrics¶
Prometheus metrics endpoint.
Response — 200 OK — plaintext Prometheus exposition format.
GET /predict/predictions/¶
Bulk read of all precomputed predictions (display columns only, no feature vectors).
Example request
Example response
[
{
"match_id": 99,
"homeTeamName": "Arsenal",
"awayTeamName": "Chelsea",
"startTimeUtc": "2025-05-10T18:00:00+00:00",
"proba_home": 0.58,
"proba_draw": 0.27,
"proba_away": 0.15,
"predicted_class": 0,
"predicted_label": "home_win",
"is_future": false,
"model_stage": "champion",
"model_run_id": "3f7a1c9d2e4b"
}
]
GET /predict/precomputed/{match_id}¶
Returns a single precomputed prediction. No Celery task, no MLflow model call.
Example request
Example response
{
"match_id": 99,
"proba_home": 0.58,
"proba_draw": 0.27,
"proba_away": 0.15,
"predicted_class": 0,
"predicted_label": "home_win",
"home_team_name": "Arsenal",
"away_team_name": "Chelsea",
"model_stage": "champion",
"model_run_id": "3f7a1c9d2e4b"
}
GET /predict/cards/¶
Predictions merged with Fonbet 1X2 odds — primary data source for the Streamlit UI.
GET /predict/region-roi/¶
Flat-stake ROI per region from the live-betting simulation pipeline.
Example response
GET /predict/odds/¶
Fonbet 1X2 odds for all matches (odd_home, odd_draw, odd_away).
GET /predict/{match_id}¶
Runs a live prediction via the Celery ml queue (synchronous, up to 30 s timeout).
Features are read from match_features.parquet. Use ?stage=challenger for the challenger model.
Example request
Example response
{
"match_id": 99,
"predicted_class": 0,
"probabilities": {"home_win": 0.58, "draw": 0.27, "away_win": 0.15},
"model_version": "champion",
"model_run_id": "3f7a1c9d2e4b"
}
GET /predict/model/info¶
MLflow model metadata for the loaded stage. Use ?stage=challenger to query challenger.
GET /livescores/¶
Match data from PostgreSQL, filterable by year/month.
Example request
GET /monitoring/drift¶
Latest Evidently feature drift report from reports/drift/latest.json.
GET /monitoring/task_status/{task_id}¶
Poll a Celery task submitted by GET /predict/{match_id}.
GET /monitoring/celery/queues¶
Active, scheduled, and reserved task counts per Celery worker.
GET /monitoring/celery/workers¶
Active queues and ping status for all connected workers.
Error handling¶
Validation errors (client-side)¶
422 Unprocessable Entityon schema validation failures404 Not Foundwhenmatch_idis absent from the parquet cache400 Bad Requestwhen an unknown model stage is requested
Server errors¶
504 Gateway Timeout— Celery worker did not respond within 30 s5xx— internal failure; logged withrequest_idfor correlation
Model traceability¶
Every prediction response includes:
model_stage— MLflow alias (e.g.champion)model_run_id— MLflow run ID for full lineage lookuppredictions_computed_at— timestamp of thebatch_inferenceDVC stage run
Related docs¶
- Serving → Inference API Contract
- ML → Model Contract
Endpoints¶
GET /healthcheck¶
Health endpoint for readiness/liveness checks.
Response
- 200 OK when the service is healthy and ready
- includes basic status fields (optional)
GET /metrics¶
Prometheus metrics endpoint.
Response
- 200 OK plaintext Prometheus format
POST /predict¶
Synchronous inference.
Use cases - interactive requests - small batch predictions
Contract - request body is validated strictly via Pydantic - unknown fields are rejected (prevents silent contract drift)
Example request
curl -X POST http://localhost:8000/predict \
-H "Content-Type: application/json" \
-d '{
"match_id": 123,
"home_team_id": 10,
"away_team_id": 20,
"match_datetime_utc": "2026-02-10T18:00:00Z"
}'
````
**Example response**
```json
{
"prediction": {
"home_win_proba": 0.45,
"draw_proba": 0.28,
"away_win_proba": 0.27
},
"model": {
"model_uri": "models:/time2bet/Production",
"model_version": "42"
},
"meta": {
"request_id": "..."
}
}
Replace fields with your actual schema. The example is intentionally generic.
POST /predict/async¶
Asynchronous inference submission (if enabled).
Behavior
- returns a job ID immediately
- job is executed by Celery workers
Example response
GET /predict/async/{job_id}¶
Fetch async inference result (if enabled).
Response
200 OKwith result when ready202 Acceptedwhen still processing (optional)404if job not found/expired
Error handling¶
Validation errors (client-side)¶
422 Unprocessable Entityon schema validation failures- response includes details about invalid fields
Server errors¶
5xxindicates internal failure- errors are logged with request_id for correlation
Model traceability¶
Every prediction response should allow traceability to:
- active model version,
- model registry URI,
- request_id (for logs),
- optionally dataset version used during training (if exposed as metadata).
Related docs¶
- Serving → Inference API Contract
- ML → Model Contract
- Monitoring → Metrics