Clinical Trial Results Table QA API
Structural QA of two normalized tables. Product page and free test form.
Endpoint
| Paid | POST https://www.spreadrun.com/api/v1/clinical-trial-table-validator, API key required, $0.25 per completed audit |
|---|---|
| Demo | POST https://www.spreadrun.com/api/demo/clinical-trial-table-validator, no key, 512 KB, 10 runs per day |
| Content-Type | application/json |
Request
A JSON object with exactly two string fields, each holding a UTF-8 CSV table with a header row. Extra fields are rejected.
{
"studiesCsv": "trial_id,condition,phase\nNCT90000001,Type 2 diabetes,PHASE3\n...",
"outcomesCsv": "trial_id,outcome_id,outcome_type,primary_endpoint,result_status,results_first_post_date\n..."
}| Field | Required columns |
|---|---|
studiesCsv | trial_id, condition, phase. One row per trial. |
outcomesCsv | trial_id, outcome_id, outcome_type, primary_endpoint, result_status, results_first_post_date. One row per outcome measure. |
Rejected with HTTP 400 and not charged: a body that is not this JSON object, a missing or empty table, missing required columns, duplicate headers, more than 40 columns, rows with a different number of cells than the header, malformed CSV, more than 10,000 rows in a table, more than 5 MiB of CSV in total, or a request body over 4.4 MB (HTTP 413). The last limit comes first in practice.
Report
| Field | Meaning |
|---|---|
status | PASS when no rule fired, otherwise FAIL. |
rowCounts | Data rows read from each table. |
fieldCoverage | Share of rows with a non-empty value, per required column, 0 to 1. |
issueCount, issueCounts | Total findings and findings per code. |
issues | Up to 1,000 findings: table, record (1-based data row, header excluded), field, code. Cell values are never echoed. |
issuesTruncated | True when more than 1,000 findings exist. |
inputSha256 | SHA-256 of each submitted table, so you can tie a report to an exact input. |
scope | What the audit does not certify. |
The audit is deterministic: the same tables always produce the same report.
Finding codes
| Code | Meaning |
|---|---|
MISSING_VALUE | A required column is empty in this row. |
INVALID_NCT_ID | trial_id is not "NCT" followed by exactly 8 digits. |
DUPLICATE_KEY | Repeats an earlier row: trial_id in the studies table, trial_id plus outcome_id in the outcomes table. |
ORPHAN_OUTCOME | The outcome points to a trial_id that has no row in the studies table. |
INVALID_OUTCOME_TYPE | outcome_type is not PRIMARY, SECONDARY or OTHER_PRE_SPECIFIED. |
INVALID_ISO_DATE | results_first_post_date is not a real calendar date written as YYYY-MM-DD. |
Example response
A paid audit of the synthetic sample tables with defects (studies, outcomes). Generated by running the real endpoint code.
{
"requestId": "7f3c2a1e-5b8d-4c6f-9e0a-1d2b3c4d5e6f",
"api": "clinical-trial-table-validator",
"mode": "paid",
"charged": true,
"priceCents": 25,
"balanceCents": 950,
"report": {
"schemaVersion": 1,
"status": "FAIL",
"rowCounts": {
"studiesCsv": 6,
"outcomesCsv": 7
},
"fieldCoverage": {
"studiesCsv": {
"condition": 1,
"phase": 1,
"trial_id": 1
},
"outcomesCsv": {
"outcome_id": 1,
"outcome_type": 1,
"primary_endpoint": 0.857143,
"result_status": 1,
"results_first_post_date": 1,
"trial_id": 1
}
},
"issueCount": 7,
"issueCounts": {
"DUPLICATE_KEY": 2,
"INVALID_ISO_DATE": 1,
"INVALID_NCT_ID": 1,
"INVALID_OUTCOME_TYPE": 1,
"MISSING_VALUE": 1,
"ORPHAN_OUTCOME": 1
},
"issues": [
{
"table": "studiesCsv",
"record": 4,
"field": "trial_id",
"code": "INVALID_NCT_ID"
},
{
"table": "studiesCsv",
"record": 6,
"field": "trial_id",
"code": "DUPLICATE_KEY"
},
{
"table": "outcomesCsv",
"record": 4,
"field": "primary_endpoint",
"code": "MISSING_VALUE"
},
{
"table": "outcomesCsv",
"record": 5,
"field": "outcome_id",
"code": "DUPLICATE_KEY"
},
{
"table": "outcomesCsv",
"record": 3,
"field": "results_first_post_date",
"code": "INVALID_ISO_DATE"
},
{
"table": "outcomesCsv",
"record": 6,
"field": "trial_id",
"code": "ORPHAN_OUTCOME"
},
{
"table": "outcomesCsv",
"record": 7,
"field": "outcome_type",
"code": "INVALID_OUTCOME_TYPE"
}
],
"issuesTruncated": false,
"inputSha256": {
"studiesCsv": "34a162e906102e1701f4f90de8eea9c57fade81ac11de5310c11b44d46ef4ae9",
"outcomesCsv": "4e355d3c00765d6bb0e63e7352f923cf5fda2d8a9d255ae1b57c0dc0639cca96"
},
"scope": "Structural QA only; no source authenticity, clinical accuracy, freshness, regulatory compliance or reuse-rights certification."
}
}Errors
See the shared error table. Example input error (HTTP 400, not charged):
{
"error": {
"code": "input_error",
"message": "studiesCsv: unique headers and required columns are mandatory (maximum 40).",
"requestId": "7f3c2a1e-5b8d-4c6f-9e0a-1d2b3c4d5e6f",
"charged": false
}
}Code samples
curl -X POST https://www.spreadrun.com/api/v1/clinical-trial-table-validator \
-H "Authorization: Bearer $SPREADRUN_API_KEY" \
-H "Content-Type: application/json" \
--data "$(jq -n --rawfile s studies.csv --rawfile o outcomes.csv '{studiesCsv: $s, outcomesCsv: $o}')"