Ingestion
Inspect load history, scheduled jobs, and database stats; upload raw data.
These endpoints back the data-operations views. Most clients use them read-only to confirm data freshness; uploading is typically handled by OSPRI.
Database stats
GET /api/v1/ingestion/stats
Live database-level counts behind the data status panel.
Response
{
"normalized_records": 934512,
"prevalence_rollups": 1751,
"db_size_bytes": 391323648,
"db_size_mb": 373.2,
"last_ingestion": "2026-05-22T07:47:00",
"vendor_count": 8,
"syndrome_count": 7
}
Ingestion history
GET /api/v1/ingestion/history
Lists recorded ingestion runs (newest last). Each run reports vendor_id, source_file,
rows_ingested, rows_skipped, rows_deduplicated, and qa_flags.
Monthly jobs
GET /api/v1/ingestion/jobs
Lists scheduled/monthly ingestion job attempts with status (queued, running, succeeded,
failed, skipped) and counts.
limit—integer, default:50— Maximum jobs to return.
Upload & ingest
POST /api/v1/ingestion/run
Upload a raw export and ingest it (parse → normalize → store → rebuild rollups). Sent as
multipart/form-data.
file—file, required — An Ignite-style.csv, or an Excel.xlsx/.xlsmwith aRaw Datasheet.vendor_id—string— Required only when the filename doesn't follow the Ignite-RPT-...pattern.
cURL
curl -X POST "https://api.previq.ospri.bio/api/v1/ingestion/run" \
-F "file=@AFC-RPT-PositiveNegative-20260409.csv" \
-F "vendor_id=AFC"
Response (ingested)
{
"data": {
"status": "ingested",
"vendor_id": "AFC",
"source_file": "AFC-RPT-PositiveNegative-20260409.csv",
"inserted": 18342,
"rows_skipped": 0,
"qa_flags": [],
"rollups": { "vendor": 412, "syndrome": 73, "cross_vendor": 61 },
"duration_seconds": 41.7
},
"meta": { "total": 1, "limit": 0, "offset": 0, "query": { "vendor_id": "AFC" } }
}
Note
Idempotent. PrevIQ hashes the file's contents; re-uploading the same file returns
status: "skipped"instead of double-counting.
Important
Only
.csv,.xlsx, and.xlsmare accepted (400otherwise). Avendor_idis required if it can't be inferred from the filename. Large files can take 30–90 seconds — keep the connection open.