POST /api/structure-confirm
Human-in-the-loop checkpoint. Accepts optional user overrides and merges them into the AI-detected structure from /api/analyze, then marks the job as ready for extraction.
Request
{
"job_id": "uuid-string",
"structure_overrides": {
"column_mapping": { "B": "unit_id", "C": "tenant_name" },
"data_start_row": 5
}
}Headers: Authorization: Bearer <token>
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
job_id | string | Yes | UUID of the job to confirm |
structure_overrides | object | No | Partial overrides to merge into structure_result |
Allowed Override Keys
Only the following keys are accepted inside structure_overrides. Any other keys are silently ignored.
| Key | Type | Description |
|---|---|---|
column_mapping | object | Map of column letters to canonical field names. Merged with existing mapping (overrides win). |
data_start_row | number | First row of Unit data (1-indexed) |
data_end_row | number | Last row of Unit data (1-indexed) |
header_row | number | Row containing column headers |
charge_orientation | string | How charges are laid out ("column" or "row") |
multi_row_per_unit | boolean | Whether each Unit spans multiple rows |
Merge Behavior
column_mappingis shallow-merged: existing mappings are preserved, and overrides are layered on top. For example, if the AI mapped{ "A": "unit_id" }and the user sends{ "B": "unit_id" }, the result is{ "A": "unit_id", "B": "unit_id" }. To fully replace the mapping, include all columns in the override.- All other keys are replaced outright when provided.
- If
structure_overridesisnull, empty, or omitted, the existingstructure_resultis left unchanged.
Processing Steps
- Authenticate via
checkAuth() - Parse JSON body and validate
job_idis present - Fetch the job row (must exist and have a
structure_result) - Merge allowed override keys into
structure_result - Update the job row:
structure_result= merged structurestructure_confirmed_at= current timestampstructure_overrides= raw overrides (stored for audit)status=analyzedstage_message="Structure confirmed — ready for extraction"
Validation
| Check | Status | Message |
|---|---|---|
Missing job_id | 400 | Missing job_id |
| Job not found | 404 | Job not found |
No structure_result on job | 400 | No structure analysis to confirm |
| Bad/missing token | 401 | Unauthorized |
Response
Success (200):
{
"job_id": "uuid-string",
"structure": { "...merged structure_result..." },
"confirmed": true
}Error (500):
{
"error": "Something went wrong"
}Notes
- This endpoint is idempotent. Calling it again overwrites the previous confirmation and re-merges overrides from scratch.
- The raw
structure_overridesobject is persisted separately from the merged result so you can always inspect what the user changed versus what the AI detected. - Confirmation is optional.
/api/extractonly requires thatstructure_resultexists (set by/api/analyze). Calling this endpoint is a human-in-the-loop step to review and optionally override the AI-detected structure before extraction.
Last updated on