Appendix A — Data models

The shapes referenced by the operations’ responses, as the specification declares them.

A.1 Annotation

Field Type Required Notes
id string (uuid) yes
bbox array of number yes
category_name string yes
parent_category string, nullable no
area number yes
coco_annotation_id number, nullable no

A.2 AnnotationReviewDecision

One decision a reviewer is asking to record.

Field Type Required Notes
suggestion_id string (uuid) yes
decision string — one of accept, reject, reclassify yes
category_id string (uuid), nullable no Required for reclassify. Refused on an accept, which carries the category the label already mapped to.
reason string, nullable no Free text, truncated at 2000 characters.

A.3 AnnotationReviewDecisionRecord

A decision as it was recorded. Never updated, never deleted.

Field Type Required Notes
id string (uuid) no
suggestion_id string (uuid) no
decision string — one of accept, reject, reclassify no
category_id string (uuid), nullable no
reason string, nullable no
decided_by string (uuid) no
decided_at string (date-time) no
annotation_id string (uuid), nullable no The annotation this decision promoted. Goes null if that annotation is later removed — the decision to accept it still happened.

A.4 AnnotationSuggestion

A box a model proposed, immutable, with the latest thing a human decided about it. Not an annotation: nothing here is a finding until someone accepts it.

Field Type Required Notes
id string (uuid) yes
attempt_id string (uuid) yes The analysis attempt that produced it, which carries the provenance.
label string yes As the backend emitted it, kept verbatim.
category_id string (uuid), nullable no The product vocabulary the label was mapped onto. Null when the label maps to nothing, which blocks acceptance until a human picks a category rather than one being invented from the wording.
category_name string, nullable no
effective_category_id string (uuid), nullable no The category a promoted annotation would carry — the reclassified one when there is one, the mapped one otherwise.
effective_category_name string, nullable no
bbox array of number yes [x, y, width, height], normalized.
area number yes
score number yes Backend-native, in [0,1]. Not comparable across backends and not a calibrated probability; thresholds apply per evaluated backend and skill revision.
created_at string (date-time) no
decision , nullable no The latest decision, or null when nobody has decided yet. A projection of an append-only log — the history is the record, this is where the suggestion stands now.

A.5 Dataset

Field Type Required Notes
id string (uuid) yes
name string yes
description string, nullable no
organization_id string (uuid) yes
owner_id string (uuid) yes
visibility string — one of private, organization no
provider string — one of aws, azure, gcp, sharepoint yes
storage_path string yes
slug string yes
default_altitude number (double), nullable no Default altitude in metres (WGS84 ellipsoidal, not AMSL) used by the 3D map when placing a location note that has no altitude of its own. Null means the dataset has no default and the client falls back to the clicked terrain height.
created_at string (date-time) yes
updated_at string (date-time) yes
organizations object no
cover_image_id string (uuid), nullable no
coverImage Image no
lifecycle string — one of indexing, ready_for_review, in_review, closed no Campaign hand-off state (W7). indexing = Data Explorer preparing; ready_for_review = sent for review; in_review/closed are reserved — no UI action sets them yet. Transitioned only via PATCH /datasets/{slug}/lifecycle, never a direct field update.

A.6 Error

The one failure shape, per CONTRACT-API-002 rule 2 (docs/api_standards/api_conventions.md). No service invents a second.

Field Type Required Notes
error string yes Human-readable and freely reworded. Never switch on this — that is what code is for.
code string no Stable, dotted, documented identifier — dataset.not_found. Added 2026-08-11 (R5) because a free-text sentence is unswitchable by a client and unusable to an agent caller, which can only surface it. Required of new and changed operations; existing ones adopt it when touched, so it is not yet marked required here.
details string, nullable no Optional free-text elaboration. Deliberately a string: an object-shaped details was proposed and rejected because changing the type is breaking for every existing consumer, while adding code is not.

A.7 GpsImage

object

A.8 Image

Field Type Required Notes
id string (uuid) yes
dataset_id string (uuid) yes
filename string yes
storage_path string yes
created_at string (date-time) yes
updated_at string (date-time) yes
metadata object, nullable no
tags array of string no
sasUrl string no SAS URL for secure access (optional)
thumbnail_url string no URL to the thumbnail stored in Supabase Storage (optional)

A.9 ImageFinding

Field Type Required Notes
id string (uuid) no
credibility string, nullable no
identified_by string, nullable no
evidence_notes string, nullable no
created_at string, nullable no
updated_at string, nullable no
equipment object, nullable no
damage_mechanism object, nullable no Set when the finding is grounded in an API-571 damage mechanism; null for an observation-grounded finding.
observation object, nullable no Set when the finding is grounded in an inspection observation (annotation category) rather than an API-571 mechanism; null otherwise. Exactly one of damage_mechanism/observation is non-null.
decisions array of object no The append-only decision history behind credibility, newest first, so decisions[0] is the verdict in force. Empty means undecided. Same shape as GET /equipment/{id}’s own decisions field — see its description for why decided_by_name can be null.

A.10 ImagePair

Field Type Required Notes
id string yes
rgb Image yes
thermal Image yes

A.11 LocationNote

Field Type Required Notes
id string (uuid) no
dataset_id string (uuid) no
created_by string (uuid) no
latitude number, nullable no
longitude number, nullable no
altitude number, nullable no
note_text string no
color string no
pdf_url string, nullable no Storage path of the attached PDF (not a URL).
pdf_filename string, nullable no
pdf_size integer, nullable no
metadata object no
tag_id string (uuid), nullable no Note tag ID from organization note_tags catalog.
created_at string (date-time) no
updated_at string (date-time) no
pdf_signed_url string, nullable no One-hour signed download URL; present only when a PDF is attached.

A.12 NoteMetadata

Extensible key-value data — location_notes.metadata is untyped jsonb by design, deliberately open to other note kinds. These are the sub-properties the Actions screen (work-order-notes.ts, actions-client.tsx) actually reads and writes for a work-order note; other kinds may use none of them, and the column accepts any additional keys.

Field Type Required Notes
kind string no What kind of note this is, e.g. “work_order”. Determines whether the Actions screen renders it as a work order.
status string — one of open, scheduled, complete no Work-order status. Defaults to “open” when kind is “work_order”.
title string no Optional one-line summary an engineer can scan.
finding_ref string no The finding this note follows from, so the reason travels with it.
scheduled_for string no Optional date this action is scheduled for.

A.13 Organization

Field Type Required Notes
id string (uuid) yes
name string yes
created_at string (date-time) yes
updated_at string (date-time) yes

A.14 ResolvedAssetImage

Field Type Required Notes
image_id string (uuid) no
filename string, nullable no
dataset_id string (uuid), nullable no
dataset_slug string, nullable no
thumbnail_url string, nullable no
tags array of string no
anomaly_count integer no Bounding-box annotations on the image. Unreviewed AI suggestions are not counted — a suggestion becomes an annotation when a reviewer accepts it.
anomalies array of object no The classes behind anomaly_count — what was found, not just how much — count-descending. A class whose annotation_categories row the caller cannot read still appears, named Unclassified, rather than being dropped.
damage_tags array of string no The image’s tags that match no asset tag in the register — the damage descriptors (“pitting”, “coating loss”). tags holds both kinds; only these are an anomaly signal.
has_anomaly boolean no anomaly_count > 0 or damage_tags is non-empty. Deliberately not tags non-empty: the confirmed set is defined by carrying the asset’s tag, so that read made every confirmed image anomalous by construction.
distance_m number, nullable no
link_confidence string, nullable no
source string — one of confirmed, nearby, evidence no confirmed — the image carries the asset’s own tag (it shows the asset); nearby — geo-linked by proximity but not tag-confirmed (the See-also set); evidence — cited by a finding and neither of the above.
ocr_suggested_tag string, nullable no On nearby images only, the equipment tag this image’s OCR placard read resolves to (what an [Approve] would confirm it as), or null when the read matches no register tag or is ambiguous. Null on confirmed/evidence images.

A.15 ThumbnailBulkRequest

Field Type Required Notes
datasetSlug string yes Slug of the dataset to process
limit integer no Maximum number of images to process (optional, processes all images without metadata if not specified)

A.16 ThumbnailBulkResponse

Field Type Required Notes
success boolean yes
processed integer yes Number of images successfully processed
errors integer yes Number of images that failed processing
total integer yes Total number of images attempted
results array of ThumbnailResult yes

A.17 ThumbnailGenerateRequest

Field Type Required Notes
imageId string (uuid) yes ID of the image to generate thumbnail for

A.18 ThumbnailGenerateResponse

Field Type Required Notes
success boolean yes
thumbnailUrl string yes URL of the generated thumbnail
imageId string (uuid) yes

A.19 ThumbnailResult

Field Type Required Notes
imageId string (uuid) yes
filename string yes
success boolean yes
thumbnailUrl string no URL of the generated thumbnail (if successful)
error string no Error message (if failed)

A.20 ActionSurfacingRequest

Field Type Required Notes
facility_id string (uuid) yes
risk_assessments array of RiskAssessmentOutput yes
existing_inspection_backlog no
operator_preferences no

A.21 ActionSurfacingResult

Field Type Required Notes
facility_id string (uuid) yes
plan_date string (date-time) yes
inspection_plan array of InspectionPlanItemOutput yes
summary PlanSummary yes

A.22 ActiveDamageSummary

Field Type Required Notes
damage_mechanism_id string (uuid) yes
mechanism_name string yes
rate number yes
rate_provenance string yes
validation_status string yes
contribution_to_pof number yes

A.23 AlignmentShift

Field Type Required Notes
stream_id string (uuid) yes
max_shift_ms integer yes
readings_shifted integer yes

A.24 AnomalyLocation

Field Type Required Notes
position_3d no
anomaly_type AnomalyType yes
severity Severity yes

A.25 AnomalyType

string — one ofhot_spot,cold_spot,gradient,other``

A.26 AutomationTier

string — one oftier1_automated,tier2_expert_required``

A.27 BoundType

string — one ofupper,lower``

A.28 CalibrationDetails

Field Type Required Notes
ut_trend_rate no
ut_reading_count no
ut_time_span_months no
thermal_corroboration no
ogi_corroboration no
model_vs_measured_delta no

A.29 ClassifyRequest

Field Type Required Notes
facility_id string (uuid) yes
equipment_ids array of string (uuid) no
validated_readings array of ValidatedReading yes
iow_limits array of IOWLimit yes
lookback_window no

A.30 ClassifyResult

Field Type Required Notes
equipment_id string (uuid) yes
exceedances array of ExceedanceEvent yes
active_exceedances array of ExceedanceEvent yes
summary ClassifySummary yes

A.31 ClassifySummary

Field Type Required Notes
total_exceedances integer yes
critical_count integer yes
standard_count integer yes
informational_count integer yes
active_count integer yes
equipment_with_exceedances integer yes

A.32 CofOutput

Field Type Required Notes
flammable no
toxic no
environmental no
financial no
score number yes

A.33 ConsistencyCheck

Field Type Required Notes
check_type ConsistencyCheckType yes
passed boolean yes
details string yes
conflicting_evidence no

A.34 ConsistencyCheckType

string — one ofmaterial_mechanism,rate_mechanism,evidence_consistency``

A.35 ConsistencyCheckedFinding

Field Type Required Notes
finding_id string (uuid) yes
consistency_status ConsistencyStatus yes
checks array of ConsistencyCheck yes
original_finding DamageFindingOutput yes

A.36 ConsistencyGateRequest

Field Type Required Notes
equipment_id string (uuid) yes
findings array of DamageFindingOutput yes
equipment_profile EquipmentProfile yes
available_inspection_records no

A.37 ConsistencyGateResult

Field Type Required Notes
equipment_id string (uuid) yes
validated_findings array of ConsistencyCheckedFinding yes
rejected_findings array of ConsistencyCheckedFinding yes

A.38 ConsistencyStatus

string — one ofconsistent,inconsistent_review_required``

A.39 CorrectiveAction

string — one ofinspect,repair,replace,operational_adjustment,monitor``

A.40 CriticalFactor

Field Type Required Notes
parameter string yes
observed_value number yes
threshold_value no
relationship string yes

A.41 DamageFindingOutput

Field Type Required Notes
id string (uuid) no
equipment_id string (uuid) yes
damage_mechanism_id string (uuid) yes
damage_mechanism_name string yes
damage_category string yes
exceedance_ids array of string (uuid) yes
predicted_rate no
predicted_rate_unit RateUnit no
rate_provenance RateProvenance no
rate_confidence number no
automation_tier AutomationTier no
engineer_review_required boolean no
mapping_rationale string no
critical_factors array of CriticalFactor no
related_mechanisms array of string (uuid) no

A.42 DamageMappingRequest

Field Type Required Notes
equipment_id string (uuid) yes
exceedances array of ExceedanceEvent yes
equipment_profile EquipmentProfile yes
api571_knowledge_base array of DamageMechanism yes

A.43 DamageMappingResult

Field Type Required Notes
equipment_id string (uuid) yes
findings array of DamageFindingOutput yes
unmapped_exceedances array of string (uuid) no

A.44 DamageMechanism

API 571 knowledge base entry.

Field Type Required Notes
id string (uuid) yes
name string yes
category string yes
critical_factors array of string no
affected_materials array of string no

A.45 DateRange

Field Type Required Notes
start string (date) yes
end string (date) yes

A.46 DetectionResult

Field Type Required Notes
detection_type DetectionType yes
confidence number yes
location_3d no

A.47 DetectionType

string — one ofgas_leak,emission,no_detection``

A.48 EquipmentProfile

Field Type Required Notes
equipment_id string (uuid) yes
equipment_class string yes
process_unit_type string yes
material_of_construction string yes
material_grade no
design_temperature no
design_pressure no
operating_temperature_range no
operating_pressure_range no
process_fluids array of string no
historical_damage_mechanisms array of string (uuid) no

A.49 ExceedanceEvent

Field Type Required Notes
id string (uuid) no
iow_limit_id string (uuid) yes
equipment_id string (uuid) yes
stream_id string (uuid) yes
iow_level IOWLevel yes
bound_type BoundType yes
limit_value number yes
start_time string (date-time) yes
end_time no
peak_value number yes
peak_time string (date-time) yes
duration_seconds no
severity_score number yes
readings_in_exceedance integer yes
parameter_type string yes
engineering_unit string yes
damage_mechanism_ids array of string (uuid) no

A.50 HTTPValidationError

Field Type Required Notes
detail array of ValidationError no

A.51 IOWLevel

string — one ofcritical,standard,informational``

A.52 IOWLimit

Active IOW limit for equipment — from the integrity data model.

Field Type Required Notes
id string (uuid) yes
equipment_id string (uuid) yes
parameter_type string yes
iow_level IOWLevel yes
bound_type BoundType yes
limit_value number yes
engineering_unit string yes
damage_mechanism_ids array of string (uuid) no

A.53 IOWStatusResponse

Field Type Required Notes
equipment_id string (uuid) yes
active_exceedances array of ExceedanceEvent no
latest_exceedances array of ExceedanceEvent no

A.54 IngestRequest

Field Type Required Notes
facility_id string (uuid) yes
streams array of SensorStreamConfig yes
time_range TimeRange yes
alignment_window_ms integer no

A.55 IngestResult

Field Type Required Notes
facility_id string (uuid) yes
time_range TimeRange yes
validated_readings array of ValidatedReading yes
quality_report QualityReport yes

A.56 IngestionModality

string — one ofscada,ogi,thermal,gas,ut``

A.57 IngestionReceipt

Field Type Required Notes
run_id string (uuid) no
modality IngestionModality yes
facility_id string (uuid) yes
equipment_id string (uuid) yes
records_accepted integer yes
records_rejected integer yes
quality_summary object no
storage_refs array of StorageRef no
errors array of string no
warnings array of string no

A.58 InspectionEffectiveness

string — one ofA,B,C,D``

A.59 InspectionIntervalOutput

Field Type Required Notes
recommended_interval_years number yes
target_risk_threshold number yes
inspection_effectiveness_target InspectionEffectiveness yes
next_inspection_date string (date) yes
basis string yes

A.60 InspectionPlanItem

Existing inspection backlog item.

Field Type Required Notes
id string (uuid) yes
equipment_id string (uuid) yes
scheduled_date string (date) yes
technique string yes

A.61 InspectionPlanItemOutput

Field Type Required Notes
id string (uuid) no
risk_assessment_id string (uuid) yes
equipment_id string (uuid) yes
facility_id string (uuid) yes
priority_rank integer yes
asset_tag string yes
asset_class string yes
current_risk_score number yes
risk_category string yes
recommended_inspection_date string (date) yes
recommended_technique string yes
recommended_coverage InspectionEffectiveness yes
justification string yes
confidence_level RateProvenance yes
corrective_action CorrectiveAction yes
corrective_action_detail no
active_damage_mechanisms array of string no
remaining_life_years no
urgency Urgency yes

A.62 InspectionRecord

Inspection record reference (used by stages 3.5, 4, 5).

Field Type Required Notes
id string (uuid) yes
equipment_id string (uuid) yes
inspection_date string (date-time) yes
technique string yes
effectiveness InspectionEffectiveness yes
findings_summary no

A.63 OGIImageRef

Field Type Required Notes
id string (uuid) yes
capture_date string (date-time) yes
equipment_id string (uuid) yes
detection_results array of DetectionResult no
storage_ref string yes

A.64 OperatorPreferences

Field Type Required Notes
max_concurrent_inspections no
preferred_techniques no
scheduling_constraints no
risk_tolerance RiskTolerance no

A.65 PipelineRunRequest

Full pipeline orchestration request.

Field Type Required Notes
facility_id string (uuid) yes
equipment_ids array of string (uuid) no
time_range TimeRange yes
mode string no

A.66 PipelineRunResult

Full pipeline orchestration result.

Field Type Required Notes
facility_id string (uuid) yes
run_id string (uuid) no
action_plan no
stage_errors object no

A.67 PlanSummary

Field Type Required Notes
total_items integer yes
immediate_items integer yes
next_turnaround_items integer yes
routine_items integer yes
low_priority_items integer yes
highest_risk_equipment array of object no
estimated_inspection_hours no

A.68 PofOutput

Field Type Required Notes
base_damage_factor number yes
inspection_effectiveness_adj number yes
management_system_factor number no
score number yes
contributing_mechanisms object no

A.69 QualityReport

Field Type Required Notes
total_readings integer yes
good_count integer yes
stale_count integer yes
interpolated_count integer yes
bad_count integer yes
unit_inconsistencies array of UnitInconsistency no
alignment_shifts array of AlignmentShift no
coverage_pct number yes

A.70 RateProvenance

string — one oflevel_a_measured,level_b_modeled,level_c_generic``

A.71 RateUnit

string — one ofmpy,mm_per_year``

A.72 ReadingQuality

string — one ofgood,stale,interpolated,bad,manual_override``

A.73 RemainingLifeOutput

Field Type Required Notes
actual_thickness no
min_thickness no
corrosion_rate no
rate_provenance no
point_estimate_years no
p90_years no
uncertainty no

A.74 RiskAssessmentOutput

Field Type Required Notes
id string (uuid) no
equipment_id string (uuid) yes
assessment_date string (date-time) yes
pof PofOutput yes
cof CofOutput yes
risk_score number yes
risk_category RiskCategory yes
risk_mode RiskMode no
remaining_life no
inspection_interval no
active_damage_mechanisms array of ActiveDamageSummary no

A.75 RiskCategory

string — one ofhigh,medium_high,medium,low``

A.76 RiskMode

string — one ofranked,calibrated``

A.77 RiskQuantRequest

Field Type Required Notes
equipment_id string (uuid) yes
equipment_profile EquipmentProfile yes
validated_assessments array of ValidatedAssessment yes
unvalidated_findings no
historical_inspections array of InspectionRecord yes
solomon_profile no

A.78 RiskQuantResult

Field Type Required Notes
equipment_id string (uuid) yes
assessment RiskAssessmentOutput yes

A.79 RiskTolerance

string — one ofconservative,standard,aggressive``

A.80 SchedulingConstraint

Field Type Required Notes
equipment_id no
unavailable_dates array of DateRange no
notes no

A.81 SensorStreamConfig

Field Type Required Notes
stream_id string (uuid) yes
tag_name string yes
source_system SourceSystem yes
engineering_unit string yes
expected_scan_interval_ms no

A.82 Severity

string — one oflow,medium,high``

A.83 SolomonProfile

Field Type Required Notes
facility_id string (uuid) yes
replacement_cost_usd no
production_rate_usd_per_day no
cof_category_overrides no

A.84 SourceSystem

string — one ofopc_ua,pi_historian,aveva,iot_gateway,manual``

A.85 StorageRef

Field Type Required Notes
bucket string yes
key string yes
content_type no

A.86 ThermalScanRef

Field Type Required Notes
id string (uuid) yes
scan_date string (date-time) yes
equipment_id string (uuid) yes
anomaly_locations array of AnomalyLocation no
storage_ref string yes

A.87 TimeRange

Field Type Required Notes
start string (date-time) yes
end string (date-time) yes

A.88 UTReading

Field Type Required Notes
id string (uuid) yes
equipment_id string (uuid) yes
cml_id string (uuid) yes
reading_date string (date-time) yes
thickness number yes
engineering_unit string no

A.89 UncertaintyBreakdown

Field Type Required Notes
measurement_tolerance number yes
code_variance number yes
model_variance number yes
combined_rl_range array of object yes

A.90 UnitInconsistency

Field Type Required Notes
stream_id string (uuid) yes
expected_unit string yes
detected_unit string yes
correction_applied boolean yes

A.91 Urgency

string — one ofimmediate,next_turnaround,routine,low_priority``

A.92 ValidatedAssessment

Field Type Required Notes
id string (uuid) no
damage_finding_id string (uuid) yes
inspection_record_ids array of string (uuid) yes
validation_status ValidationStatus yes
validated_rate no
validated_rate_unit RateUnit no
confidence_calibration number no
evidence_summary string no
calibration_details no

A.93 ValidatedReading

Field Type Required Notes
stream_id string (uuid) yes
timestamp string (date-time) yes
value number yes
quality ReadingQuality yes
aligned boolean yes
original_timestamp no
original_value no
engineering_unit string yes
parameter_type no

A.94 ValidationError

Field Type Required Notes
loc array of object yes
msg string yes
type string yes
input no
ctx object no

A.95 ValidationRequest

Field Type Required Notes
equipment_id string (uuid) yes
findings array of ConsistencyCheckedFinding yes
inspection_records array of InspectionRecord yes
ut_readings array of UTReading yes
thermal_scans no
ogi_imagery no

A.96 ValidationResult

Field Type Required Notes
equipment_id string (uuid) yes
validated_assessments array of ValidatedAssessment yes
unvalidated_findings array of string (uuid) no

A.97 ValidationStatus

string — one ofconfirmed,modified,rejected,insufficient_evidence``