export interface ApiEnvelope { data: T } export interface ApiError { code: string message: string details: Record | unknown[] } export interface ApiErrorEnvelope { error: ApiError } export interface ProjectRead { id: string name: string description?: string | null region: string status: string created_at?: string | null updated_at?: string | null } export interface ProjectCreate { name: string description?: string | null region?: string } export interface ProjectUpdate extends Partial { status?: 'active' | 'archived' } export interface ProjectListResponse { items: ProjectRead[] total: number limit: number offset: number } export interface DemoWorkflowResponse { project_id: string area_id: string reference_dataset_id: string candidate_dataset_id: string raster_dataset_id?: string | null quality_check_id: string metric_count: number status: string message: string created: boolean } export interface AreaRead { id: string project_id: string name: string original_crs?: string | null area_m2?: number | null created_at?: string | null geometry_type?: string | null geometry?: GeoJSON.Polygon | GeoJSON.MultiPolygon | null } export interface AreaCreate { name: string geometry: GeoJSON.Polygon | GeoJSON.MultiPolygon crs?: string } export interface AreaListResponse { items: AreaRead[] total: number limit: number offset: number } export interface MunicipalitySearchItem { niscode: string name: string name_nl?: string | null name_fr?: string | null name_de?: string | null } export interface MunicipalitySearchResponse { items: MunicipalitySearchItem[] total: number } export interface DatasetCreateResponse { id: string name: string dataset_type: string source: string dataset_role?: string source_name?: string | null reference_layer_name?: string | null source_metadata?: Record | null provenance_metadata?: Record | null source_registry_id?: string | null source_snapshot_id?: string | null data_contract_key?: string | null data_contract_version?: string | null validation_status?: string | null validation_report_json?: Record | null provenance_status?: string | null lineage_status?: string | null quarantine_status?: string | null imported_at?: string | null temporal_series_key?: string | null observed_at?: string | null valid_from?: string | null valid_to?: string | null temporal_granularity?: string | null source_version?: string | null project_id: string area_id?: string | null storage_path?: string | null original_filename?: string | null stored_filename?: string | null content_type?: string | null size_bytes?: number | null checksum_sha256?: string | null crs?: string | null bounds_json?: Record | null metadata_json?: Record | null vector_summary?: VectorSummary | null status: string derived_from_dataset_id?: string | null created_at?: string | null feature_count?: number | null } export interface JobRead { id: string job_type: string status: string project_id: string dataset_id?: string | null input_dataset_id?: string | null output_dataset_id?: string | null parameters_json: Record result_json?: Record | null error_message?: string | null created_at?: string | null started_at?: string | null finished_at?: string | null } export interface JobListResponse { items: JobRead[] total: number limit: number offset: number } export interface AoiOperationPartition { id: string partition_key: string provider_key: string product_key: string ordinal: number status: 'queued' | 'running' | 'success' | 'failed' | 'skipped' attempt_count: number max_attempts: number checkpoint_json?: Record | null result_json?: Record | null error_message?: string | null } export interface AoiOperation { id: string project_id: string area_id?: string | null parent_job_id?: string | null operation_type: string status: 'queued' | 'running' | 'partial' | 'success' | 'failed' | 'cancelled' request_json: Record plan_json: Record result_json?: Record | null error_message?: string | null progress: number partition_counts: Record partitions: AoiOperationPartition[] created_at?: string | null started_at?: string | null finished_at?: string | null } export interface AoiOperationListResponse { items: AoiOperation[] total: number } export interface VectorSummary { feature_count?: number | null geometry_types?: string[] | null bounds_json?: Record | null approximate_area_m2?: number | null crs?: string | null feature_geometry_count?: number | null invalid_features?: number | null crs_assumed?: boolean | null } export interface VectorSummaryResponse { feature_count?: number | null geometry_types?: string[] | null bounds_json?: Record | null approximate_area_m2?: number | null crs?: string | null feature_geometry_count?: number | null invalid_features?: number | null crs_assumed?: boolean | null } export interface RasterMetadataResponse { driver: string dataset_id?: string width: number height: number band_count: number crs?: string | null bounds?: number[] resolution?: number[] dtype?: string[] nodata?: unknown transform?: string[] | number[] | null path?: string size_bytes?: number | null checksum_sha256?: string | null operation?: string | null operation_parameters?: Record | null source_dataset_id?: string | null } export interface RasterInspectResponse { dataset_id: string ready: boolean metadata: Record } export interface RasterPreviewPayload { path: string format: string width: number | null height: number | null } export interface RasterPreviewResponse { dataset_id: string ready: boolean preview: RasterPreviewPayload metadata?: Record } export interface RasterBandStats { band_index: number dtype: string | null min: number | null max: number | null mean: number | null std: number | null nodata_count: number nodata_ratio: number valid_pixel_count: number histogram: number[] | null histogram_bins: number[] | null } export interface RasterStatsResponse { dataset_id: string source_dataset_id?: string | null bands: RasterBandStats[] generated_at?: string | null } export interface RasterNdviRequest { nir_band: number red_band: number output_name?: string } export interface RasterNdwiRequest { green_band: number nir_band: number output_name?: string } export interface RasterNdbiRequest { swir_band: number nir_band: number output_name?: string } export interface RasterTileManifestTile { path: string pixel_window: number[] bounds: number[] transform: number[] index: number } export interface RasterTileManifest { tile_set_id: string source_dataset_id: string source_raster_id: string bounds: number[] tile_size: number overlap: number parameters: Record created_at: string tile_paths: string[] count: number tiles: RasterTileManifestTile[] } export interface RasterTileResponse { dataset_id: string ready: boolean operation: string tile_set_id: string tile_size: number overlap: number manifest_path: string count: number manifest: RasterTileManifest } export interface RasterTileHandoff { manifest_path: string tile_set_id?: string | null tile_size?: number | null overlap?: number | null count?: number | null source_dataset_id?: string | null created_at?: string | null } export interface VectorBBoxResponse { dataset_id: string bounds_json: Record | null feature_count: number crs?: string | null } export interface VectorStatsResponse { dataset_id: string feature_count: number geometry_type_summary: Record bounds_json: Record | null crs?: string | null } export interface VectorSelectionBBox { min_x: number min_y: number max_x: number max_y: number crs?: 'EPSG:4326' } export interface OrthophotoAcquireRequest { bbox: VectorSelectionBBox area_id?: string product_key?: string force_refresh?: boolean resolution_m?: number } export interface OrthophotoProductRead { key: string provider: string display_name: string observation_label: string temporal_granularity: string native_resolution_m: number supports_detection: boolean color_mode: string catalog_url: string coverage_zone: string attribution: string license_note: string limitation_message: string } export interface OrthophotoAcquisitionResult { output_dataset_id: string reused: boolean provider: string product_key: string display_name: string observation_label: string temporal_granularity: string supports_detection: boolean layer: string width: number height: number resolution_m: number bbox_epsg4326: number[] bbox_epsg31370: number[] attribution: string limitation_message: string } export interface DhmvAcquireRequest { bbox: VectorSelectionBBox area_id?: string | null product_key?: 'dtm_1m' | 'dsm_1m' resolution_m?: number | null force_refresh?: boolean } export interface DhmvProductRead { key: 'dtm_1m' | 'dsm_1m' display_name: string surface_model: 'terrain' | 'surface' coverage_id: string native_resolution_m: number source_crs: string vertical_reference: string acquisition_period: string catalog_url: string attribution: string limitation_message: string } export interface SpwTerrainAcquireRequest { bbox: VectorSelectionBBox area_id?: string | null product_key?: 'spw_mnt_1m_2021_2022' resolution_m?: number | null force_refresh?: boolean } export interface SpwTerrainProductRead { key: 'spw_mnt_1m_2021_2022' display_name: string surface_model: 'terrain' source_filename: string native_resolution_m: number analysis_resolution_m: number source_crs: 'EPSG:3812' vertical_reference: string acquisition_period: string catalog_url: string attribution: string license_note: string limitation_message: string coverage_zones: string[] configured: boolean status: string } export interface GrbAcquireRequest { bbox: VectorSelectionBBox area_id?: string | null product_key: 'buildings' | 'roads' | 'water' | 'parcels' force_refresh?: boolean } export interface GrbProductRead { key: 'buildings' | 'roads' | 'water' | 'parcels' display_name: string reference_layer_name: string collections: string[] geometry_types: string[] source_crs: 'EPSG:4326' authority_level: 'authoritative' catalog_url: string attribution: string license_note: string limitation_message: string } export interface OfficialVectorAcquireRequest { bbox: VectorSelectionBBox area_id?: string | null product_key: string force_refresh?: boolean } export interface OfficialVectorProductRead { key: string display_name: string theme: 'buildings' | 'roads' | 'water' | 'parcels' | 'nature_value' | 'soil' provider: string source_name: string reference_layer_name: string service_type: 'OGC API Features' | 'WFS 2.0' | 'ArcGIS REST' collection: string geometry_types: string[] source_crs: string source_version: string observation_label: string authority_level: 'authoritative' | 'authoritative_historical_baseline' catalog_url: string attribution: string license_note: string limitation_message: string coverage_zones: string[] } export interface TerrainSelectionResponse { dataset_id: string dataset_ids: string[] partition_count: number product_key: string surface_model: 'terrain' | 'surface' selection_bbox: VectorSelectionBBox selection_area_id?: string | null sample_count: number slope_sample_count: number coverage_ratio: number /** Set when the selection was finer than one source cell and widened. */ cell_selection_warning?: string | null resolution_m: number vertical_reference: string summary: { metric_label: string metric_value: number metric_unit: string aggregation_method: string primary_metric_key: string metrics: VectorSelectionMetric[] } unsupported_metrics: string[] limitation_message: string generated_at: string } export interface FloodHazardAcquireRequest { bbox: VectorSelectionBBox area_id?: string | null product_key?: string resolution_m?: number | null force_refresh?: boolean } export interface FloodHazardProductRead { key: string display_name: string mechanism: 'pluviaal' | 'fluviaal' climate_context: string probability_class: string return_period_years: number coverage_id: string native_resolution_m: number source_crs: string source_value_unit: 'cm' normalized_value_unit: 'm' published_on: string catalog_url: string attribution: string limitation_message: string } export interface FloodHazardSelectionResponse { dataset_id: string dataset_ids: string[] partition_count: number product_key: string mechanism: 'pluviaal' | 'fluviaal' climate_context: string probability_class: string return_period_years: number selection_bbox: VectorSelectionBBox selection_area_id?: string | null selected_cell_count: number /** Cells the flood model actually covers inside the selection. */ valid_cell_count?: number no_data_cell_count?: number data_coverage_ratio?: number inundated_cell_count: number /** Share of the *modelled* cells; null when nothing was modelled. */ inundated_fraction: number | null coverage_warning?: string | null resolution_m: number summary: { metric_label: string metric_value: number metric_unit: string aggregation_method: string primary_metric_key: string metrics: VectorSelectionMetric[] } unsupported_metrics: string[] limitation_message: string generated_at: string } export interface BathymetryProfileAcquireRequest { bbox: VectorSelectionBBox area_id?: string | null force_refresh?: boolean } export interface BathymetrySourceRead { key: string display_name: string owner: string authority_level: 'authoritative' | 'contextual' geographic_coverage: string data_kind: string query_modes: string[] vertical_reference: string horizontal_crs: string native_resolution?: string | null integration_status: 'operational' | 'probe_only' | 'available_not_integrated' | 'catalog_only' acquisition_supported: boolean configured: boolean service_url?: string | null catalog_url: string attribution: string license_note: string limitation_message: string } export interface BathymetrySourceProbeRead { source_key: 'mdk_bcp_bathymetry' status: | 'disabled' | 'invalid_configuration' | 'tls_error' | 'endpoint_unavailable' | 'invalid_capabilities' | 'reachable' configured_url: string capabilities_url?: string | null tls_verified: boolean capabilities_reachable: boolean acquisition_supported: false wcs_version?: string | null coverage_identifiers: string[] advertised_formats: string[] advertised_crs: string[] response_sha256?: string | null checked_at: string message: string limitation_message: string } export interface BathymetryRasterSelectionResponse { dataset_id: string product_key: 'spw_bathymetry_50cm_mdng' selection_bbox: VectorSelectionBBox selection_area_id?: string | null selected_cell_count: number valid_cell_count: number coverage_ratio: number /** Set when the selection was finer than one source cell and widened. */ cell_selection_warning?: string | null resolution_m: number vertical_reference: 'mDNG' survey_period: string summary: { metric_label: string metric_value: number metric_unit: string aggregation_method: string primary_metric_key: string metrics: VectorSelectionMetric[] } unsupported_metrics: string[] limitation_message: string generated_at: string } export interface ThematicRasterAcquireRequest { bbox: VectorSelectionBBox area_id?: string | null product_key: string force_refresh?: boolean } export interface ThematicRasterProductRead { key: string display_name: string theme: 'space_occupation' | 'open_space' | 'forest' | 'agriculture' | 'population' | 'accessibility' | 'services' | 'land_cover' metric_kind: 'binary_area' | 'population_density' | 'index_score' | 'normalized_score' | 'categorical_area' coverage_id: string native_resolution_m: number analysis_resolution_m?: number | null source_crs: 'EPSG:31370' | 'EPSG:3812' source_value_unit: string observation_year: number source_version: string catalog_url: string attribution: string license_note: string legend_min_label: string legend_max_label: string included_source_values: number[] limitation_message: string coverage_zones: string[] configured: boolean status: 'configured' | 'source_not_provisioned' } export interface ThematicRasterSelectionResponse { dataset_id: string product_key: string theme: ThematicRasterProductRead['theme'] metric_kind: ThematicRasterProductRead['metric_kind'] selection_bbox: VectorSelectionBBox selection_area_id?: string | null selected_cell_count: number valid_cell_count: number coverage_ratio: number /** Set when the selection was finer than one source cell and widened. */ cell_selection_warning?: string | null resolution_m: number observation_year: number summary: { metric_label: string metric_value: number metric_unit: string aggregation_method: string primary_metric_key: string metrics: Array } unsupported_metrics: string[] limitation_message: string generated_at: string } export interface MapImageOverlay { url: string bbox: [number, number, number, number] label: string opacity?: number } export interface MapViewportState { bbox: VectorSelectionBBox zoom: number } export interface VectorSelectionRequest { bbox: VectorSelectionBBox area_id?: string limit?: number } export interface VectorSelectionDeriveRequest extends VectorSelectionRequest { output_name?: string } export interface VectorSelectionResponse { selection_bbox: VectorSelectionBBox selection_area_id?: string | null feature_count: number total_feature_count?: number | null limit: number truncated: boolean geojson: GeoJSON.FeatureCollection summary?: VectorSelectionSummary | null partition_count?: number | null available_partition_count?: number | null partition_scope_key?: string | null source_name?: string | null dataset_ids?: string[] } export interface VectorSelectionSummary { metric_label: string metric_value: number metric_unit: string aggregation_method: string primary_metric_key?: string | null /** * Whole features touching the selection. Area and length metrics clip to the * selection, so these two fields say how far the populations diverge. */ feature_count: number fully_covered_feature_count?: number | null partially_covered_feature_count?: number | null selection_edge_warning?: string | null is_estimate: boolean warning?: string | null metrics?: VectorSelectionMetric[] } export interface VectorSelectionMetric { metric_key: string metric_label: string metric_value: number metric_unit: string aggregation_method: string is_estimate: boolean warning?: string | null } export interface DatasetTemporalUpdate { temporal_series_key: string observed_at: string valid_from?: string | null valid_to?: string | null temporal_granularity?: string source_version?: string | null } export interface DatasetVersionRead { id: string dataset_id: string version: number storage_path?: string | null source_version?: string | null observed_at?: string | null valid_from?: string | null valid_to?: string | null checksum_sha256?: string | null source_metadata?: Record | null provenance_metadata?: Record | null created_at?: string | null } export interface TemporalComparisonRequest { earlier_dataset_id: string later_dataset_id: string bbox: VectorSelectionBBox area_id?: string | null preview_limit?: number } export interface TemporalDatasetRef { id: string name: string observed_at: string source_version?: string | null } export interface TemporalMetricComparison { metric_key: string label: string unit: string aggregation_method: string earlier_value: number later_value: number absolute_change: number percent_change?: number | null is_estimate: boolean warning?: string | null } export interface TemporalObservationMetric { metric_key: string label: string value: number unit: string aggregation_method: string is_estimate: boolean } export interface TemporalObservation { dataset: TemporalDatasetRef metrics: TemporalObservationMetric[] } export interface TemporalObjectChanges { available: boolean added_count?: number | null removed_count?: number | null modified_count?: number | null unchanged_count?: number | null } export interface TemporalComparisonResponse { temporal_series_key: string earlier: TemporalDatasetRef later: TemporalDatasetRef selection_bbox: VectorSelectionBBox selection_area_id?: string | null metric: TemporalMetricComparison metrics: TemporalMetricComparison[] timeline: TemporalObservation[] object_changes: TemporalObjectChanges geojson: GeoJSON.FeatureCollection warnings: string[] generated_at: string } export interface TemporalSeriesDataset { id: string name: string observed_at: string source_version?: string | null feature_count?: number | null } export interface TemporalSeriesRead { temporal_series_key: string source_name?: string | null reference_layer_name?: string | null dataset_count: number first_observed_at: string last_observed_at: string datasets: TemporalSeriesDataset[] } export interface TemporalSeriesListResponse { items: TemporalSeriesRead[] total: number } export interface DatasetListResponse { items: DatasetCreateResponse[] total: number limit: number offset: number } export type SourceFreshnessStatus = 'current' | 'due' | 'review_required' | 'local' export interface SourceIntegritySummary { missing_version_count: number checksum_mismatch_count: number missing_storage_file_count: number size_mismatch_count: number } export interface SourceFreshnessItem { source_name: string display_name: string dataset_count: number ready_count: number version_count: number latest_imported_at?: string | null latest_observed_at?: string | null latest_source_version?: string | null refresh_policy: 'rolling_snapshot' | 'annual_release' | 'edition' | 'scenario' | 'archive' | 'local' review_interval_days?: number | null next_review_at?: string | null status: SourceFreshnessStatus historical_series: boolean auto_refresh_supported: false reason: string recommended_action: string integrity: SourceIntegritySummary } export interface SourceFreshnessReport { project_id: string generated_at: string summary: { source_count: number dataset_count: number current_count: number due_count: number review_required_count: number local_count: number sources_with_integrity_issues: number integrity_issue_count: number } items: SourceFreshnessItem[] limitations: string[] } export type SourceCatalogProbeStatus = 'available' | 'degraded' | 'unavailable' | 'disabled' export type SourceCatalogComparisonStatus = 'same' | 'different' | 'not_comparable' | 'no_local_data' | 'unavailable' export interface SourceCatalogProbeItem { source_name: string display_name: string service_type: 'WFS' | 'WMS' | 'HTML' | 'DCAT' endpoint_url: string status: SourceCatalogProbeStatus reachable: boolean checked_at: string cached: boolean expected_layers: string[] matched_layers: string[] missing_layers: string[] advertised_layer_count: number metadata_url?: string | null metadata_identifier?: string | null remote_title?: string | null remote_version?: string | null remote_modified_at?: string | null remote_published_at?: string | null local_source_version?: string | null comparison_status: SourceCatalogComparisonStatus capabilities_sha256?: string | null capabilities_etag?: string | null capabilities_last_modified_at?: string | null message: string error_code?: string | null } export interface SourceCatalogProbeReport { project_id: string generated_at: string summary: { provider_count: number available_count: number degraded_count: number unavailable_count: number disabled_count: number different_version_count: number } items: SourceCatalogProbeItem[] limitations: string[] } export type GrbRefreshLayerStatus = | 'current' | 'update_available' | 'not_loaded' | 'review_required' | 'remote_unavailable' export interface GrbRefreshLayerPlan { theme: 'buildings' | 'roads' | 'water' | 'parcels' display_name: string collections: string[] temporal_series_key: string status: GrbRefreshLayerStatus local_dataset_id?: string | null local_source_version?: string | null local_observed_at?: string | null local_imported_at?: string | null local_feature_count?: number | null local_size_bytes?: number | null retained_after_refresh: boolean action_message: string } export interface GrbRefreshPlan { project_id: string scope: string generated_at: string remote_status: string remote_version?: string | null remote_edition_date?: string | null catalog_checked_at?: string | null summary: { layer_count: number current_count: number update_available_count: number not_loaded_count: number review_required_count: number remote_unavailable_count: number new_dataset_count_if_applied: number retained_dataset_count: number current_feature_count: number current_size_bytes: number } layers: GrbRefreshLayerPlan[] execution_mode: 'operator_stage_then_apply' staging_required: true automatic_import: false destructive_replacement: false message: string limitations: string[] } export interface GeojsonEnvelopeResponse { data: object } export interface ChangeDetectionRequest { source_dataset_id: string target_dataset_id: string iou_threshold: number /** Below this the footprints are separate objects rather than one redrawn. */ modified_threshold?: number include_unchanged: boolean /** Without a selection the comparison covers both datasets in full. */ bbox?: VectorSelectionBBox | null area_id?: string | null preview_limit?: number } export interface ChangeDetectionSummary { source_dataset_id: string target_dataset_id: string source_feature_count: number target_feature_count: number added_count: number removed_count: number /** A footprint that was redrawn, not demolished and rebuilt. */ modified_count?: number unchanged_count: number iou_threshold: number modified_iou_threshold?: number | null selection_area_id?: string | null /** Counts cover the whole selection; the GeoJSON is capped. */ preview_limit?: number | null preview_truncated?: boolean warnings: string[] generated_at: string geojson: GeoJSON.FeatureCollection } export interface ProviderCapability { provider_name: string display_name: string authority_level: 'authoritative' | 'contextual' | 'manual' | 'fixture' | string supported_layers: string[] supported_geometry_types: string[] supported_query_modes: string[] fetch_signature: string configured: boolean status: string limitation_message: string attribution: string license_note: string not_configured_reason: string | null } export type CoverageStatus = 'operational' | 'partial' | 'not_configured' | 'unsupported' export interface CoverageBBox { minx: number miny: number maxx: number maxy: number } export interface CoverageSourceContract { source_name: string display_name: string authority_level: 'authoritative' | 'official_context' | 'contextual' coverage_zones: string[] themes: string[] native_layers: string[] supported_geometry_types: string[] acquisition_mode: 'operator_archive' | 'operator_wfs' | 'bounded_api' | 'bounded_raster' | 'catalog_only' integration_status: CoverageStatus source_url: string attribution: string license_note: string limitation_message: string } export interface CoverageCatalogResponse { themes: string[] zones: string[] statuses: CoverageStatus[] sources: CoverageSourceContract[] } export interface CoverageResolutionItem { zone: string theme: string status: CoverageStatus source_names: string[] materialized_dataset_ids: string[] evidence: Array<{ dataset_id: string source_name: string authority_level: 'authoritative' | 'official_context' | 'contextual' source_version?: string | null observed_at?: string | null published_at?: string | null crs?: string | null resolution?: Record | null coverage_bbox_epsg4326?: number[] | null attribution?: string | null license_note?: string | null checksum_sha256?: string | null }> limitation_message: string } export interface CoverageResolveResponse { project_id: string bbox: CoverageBBox requested_themes: string[] intersected_zones: string[] outside_supported_scope: boolean items: CoverageResolutionItem[] warnings: string[] } export interface SystemCapabilitiesResponse { status: string service: string version: string database: string | null postgis: boolean rasterio: boolean geopandas: boolean yolo: boolean | string sam: boolean | string grb: string sentinel: string providers: ProviderCapability[] } export interface AssistantModelRead { name: string size_bytes?: number | null parameter_size?: string | null quantization_level?: string | null capabilities: string[] } export interface AssistantModelsResponse { items: AssistantModelRead[] total: number default_model?: string | null } export interface AssistantStatus { enabled: boolean reachable: boolean status: string base_url: string default_model?: string | null model_count: number limitation_message: string } export interface AssistantChatMessage { role: 'user' | 'assistant' content: string } export interface AssistantQueryRequest { question: string model?: string | null bbox?: VectorSelectionBBox | null area_id?: string | null history?: AssistantChatMessage[] } export interface AssistantContextMetric { theme: string label: string value: number unit: string source: string dataset_id: string observed_at?: string | null is_estimate: boolean } export interface AssistantTemporalSeries { temporal_series_key: string label: string source: string first_year: number last_year: number observation_count: number } export interface AssistantQueryResponse { answer: string model: string scope_label: string context_metrics: AssistantContextMetric[] temporal_series: AssistantTemporalSeries[] source_dataset_ids: string[] warnings: string[] generated_at: string } export interface ProviderCapabilitiesResponse { providers: ProviderCapability[] } export interface ProviderLayersResponse { provider_name: string layers: string[] } export interface ProviderStatusResponse { provider_name: string configured: boolean status: string limitation_message: string } export interface ProviderImportResponse { provider_name: string status: string message: string requested_layers: string[] dataset_id: string | null dataset_role?: string | null source_name?: string | null } export interface DetectionModelCapability { model_id: string display_name: string framework: string task_type: string supported_classes: string[] configured: boolean status: string limitation_message: string version?: string | null training_scope?: string | null validation_scope?: string | null validated_regions: string[] nationally_validated: boolean operator_review_required: boolean } export interface DetectionModelsResponse { models: DetectionModelCapability[] } export interface ModelAssetRead { model_asset_id: string filename: string display_name: string model_path: string suffix: string framework: string task_type: string size_bytes: number sha256: string active: boolean runtime_available: boolean runtime_status: string governed_validation_status: string promotion_status: string status: string limitation_message: string will_download_models: boolean } export interface ModelAssetListResponse { items: ModelAssetRead[] total: number model_directory: string } export interface YoloPreflightChecks { enabled: boolean dependencies_available?: boolean | null accelerator_ready?: boolean | null model_path_set?: boolean | null model_file_exists?: boolean | null model_load_requested: boolean model_load_ok?: boolean | null manifest_path_set?: boolean | null manifest_valid?: boolean | null tile_paths_exist?: boolean | null tile_limit_ok?: boolean | null } export interface YoloPreflightRuntime { dependencies_assumed: boolean model_directory?: string | null yolo_config_dir?: string | null torch_version?: string | null ultralytics_version?: string | null cuda_available?: boolean | null } export interface YoloPreflightResponse { model_id: string model_asset_id?: string | null model_path?: string | null tile_manifest_path?: string | null status: string message: string checks: YoloPreflightChecks runtime: YoloPreflightRuntime tile_count: number max_tiles: number will_download_models: boolean will_run_inference: boolean error_code?: string | null } export interface DetectionRunRequest { project_id: string dataset_id: string model_id: string model_asset_id?: string | null confidence_threshold: number class_filter?: string[] | null tile_manifest_path?: string | null parameters_json?: Record } export interface DetectionRunResponse { analysis_run_id: string job_id: string project_id: string dataset_id: string model_id: string status: string detection_count: number error_code?: string | null message: string } export interface DetectionRunRead { id: string project_id: string dataset_id?: string | null job_id?: string | null analysis_type: string status: string model_name?: string | null model_version?: string | null parameters_json: Record result_json?: Record | null error_message?: string | null created_at?: string | null started_at?: string | null finished_at?: string | null } export interface DetectionRunListResponse { /** The most recent page; `total` counts every run. */ items: DetectionRunRead[] total: number limit?: number | null offset?: number truncated?: boolean } export interface DetectionRead { id: string project_id: string dataset_id?: string | null analysis_run_id?: string | null job_id?: string | null model_name: string model_version?: string | null class_name: string confidence: number bbox_json?: Record | null source_tile_path?: string | null properties_json?: Record | null created_at?: string | null } export interface DetectionListResponse { /** One page of results; `total` is the complete population. */ items: DetectionRead[] total: number limit?: number | null offset?: number truncated?: boolean } export interface DetectionQaRequest { reference_dataset_id: string iou_threshold: number class_name?: string | null min_confidence?: number | null /** * Confidence cuts to report next to the run's own operating point. They are * read off one matching pass, so a sweep costs no extra inference. */ calibration_thresholds?: number[] } /** One confidence cut, derived from a single run rather than a run of its own. */ export interface DetectionCalibrationPoint { min_confidence: number confidence_threshold: number | null candidate_count: number true_positives: number false_positives: number false_negatives: number precision: number | null recall: number | null f1_score: number | null best_f1_in_sweep: boolean } export interface DetectionQaResult { status: string quality_check_id: string analysis_run_id: string reference_dataset_id: string candidate_feature_count: number reference_feature_count: number candidate_feature_count_raw?: number reference_feature_count_raw?: number matches: number false_positives: number false_negatives: number precision?: number | null recall?: number | null f1_score?: number | null mean_iou?: number | null iou_threshold: number warnings: string[] coverage?: { applied: boolean mode: string manifest_path?: string | null tile_count: number source_crs_values: string[] candidate_raw_count: number candidate_evaluated_count: number candidate_excluded_outside_count: number candidate_clipped_boundary_count: number reference_raw_count: number reference_evaluated_count: number reference_excluded_outside_count: number reference_clipped_boundary_count: number } box_to_footprint_diagnostics?: { diagnostic_only: boolean canonical_method: string diagnostic_method: string iou_threshold: number /** Whether the candidates are detector boxes or true footprint polygons. */ candidate_geometry_mode?: string interpretation?: string strict_matches: number envelope_matches: number possible_box_to_footprint_mismatch_count: number envelope_false_positives: number envelope_false_negatives: number envelope_precision?: number | null envelope_recall?: number | null envelope_f1_score?: number | null envelope_mean_iou?: number | null envelope_precision_recall_curve?: PrecisionRecallCurve } precision_recall_curve?: PrecisionRecallCurve calibration_sweep?: DetectionCalibrationPoint[] } /** * Threshold-independent view of a detection run: precision and recall at every * confidence value that occurs, so two models can be compared without both * being read at one arbitrary cut. */ export interface PrecisionRecallCurve { iou_threshold: number reference_count: number candidate_count: number average_precision: number best_f1: number best_f1_threshold: number | null best_f1_precision?: number | null best_f1_recall?: number | null points: PrecisionRecallPoint[] } export interface PrecisionRecallPoint { confidence_threshold: number candidate_count: number true_positives: number false_positives: number false_negatives: number precision: number recall: number f1_score: number } export type SegmentationModelCapability = DetectionModelCapability export interface SegmentationModelsResponse { models: SegmentationModelCapability[] } export interface SegmentationRunRequest { project_id: string dataset_id: string model_id: string confidence_threshold: number class_filter?: string[] | null tile_manifest_path?: string | null parameters_json?: Record } export interface SegmentationRunResponse { analysis_run_id: string job_id: string project_id: string dataset_id: string model_id: string status: string segmentation_count: number error_code?: string | null message: string } export interface SegmentationRunRead { id: string project_id: string dataset_id?: string | null job_id?: string | null analysis_type: string status: string model_name?: string | null model_version?: string | null parameters_json: Record result_json?: Record | null error_message?: string | null created_at?: string | null started_at?: string | null finished_at?: string | null } export interface SegmentationRunListResponse { /** The most recent page; `total` counts every run. */ items: SegmentationRunRead[] total: number limit?: number | null offset?: number truncated?: boolean } export interface SegmentationRead { id: string project_id: string dataset_id?: string | null analysis_run_id?: string | null job_id?: string | null model_name: string model_version?: string | null class_name: string confidence?: number | null bbox_json?: Record | null area_m2?: number | null mask_path?: string | null source_tile_path?: string | null tile_index?: number | null properties_json?: Record | null provenance_json?: Record | null created_at?: string | null } export interface SegmentationListResponse { /** One page of results; `total` is the complete population. */ items: SegmentationRead[] total: number limit?: number | null offset?: number truncated?: boolean } export interface SegmentationQaRequest { reference_dataset_id: string iou_threshold: number class_name?: string | null min_confidence?: number | null /** Read off the one matching pass, exactly as for detection. */ calibration_thresholds?: number[] } export type SegmentationQaResult = DetectionQaResult export interface QaComparisonRequest { candidate_dataset_id: string reference_dataset_id: string iou_threshold: number area_id?: string | null } export interface QaComparisonResult { status: string warnings: string[] candidate_feature_count: number reference_feature_count: number matches: number false_positives: number false_negatives: number precision: number | null recall: number | null f1_score: number | null mean_iou: number | null iou_threshold: number unsupported_geometry: boolean unsupported_geometries: string[] match_evidence?: Record[] false_positive_evidence?: Record[] false_negative_evidence?: Record[] generated_at: string quality_check_id?: string } export interface MetricRead { id: string quality_check_id?: string | null analysis_run_id?: string | null metric_key: string metric_value?: number | null metric_unit?: string | null label?: string | null metadata_json?: Record | null created_at?: string | null } export interface QualityCheckRead { id: string project_id: string job_id?: string | null analysis_run_id?: string | null candidate_dataset_id?: string | null reference_dataset_id: string check_type: string status: string score?: number | null parameters_json?: Record | null findings_json?: Record | null created_at?: string | null completed_at?: string | null metrics: MetricRead[] } export interface QualityCheckListResponse { items: QualityCheckRead[] total: number limit: number offset: number } export interface QualityEvidenceGeoJsonResponse { quality_check_id: string project_id: string candidate_dataset_id?: string | null reference_dataset_id: string analysis_run_id?: string | null /** * Features drawn. The overlay is capped so a regional check stays * reviewable — misses and false positives first — while the counts in the * quality check itself remain complete. */ feature_count: number total_feature_count?: number | null role_counts?: Record truncated?: boolean limit?: number | null warnings: string[] geojson: GeoJSON.FeatureCollection } export type DetectionEvidenceRole = 'false_positive' | 'false_negative' export type DetectionReviewDecision = | 'confirmed_model_false_positive' | 'confirmed_model_false_negative' | 'reference_gap_or_change' | 'qa_alignment_mismatch' | 'imagery_obscured_or_uncertain' | 'uncertain' | 'unreviewed' export interface DetectionReviewUpsert { evidence_role: DetectionEvidenceRole evidence_feature_id: string decision: DetectionReviewDecision notes?: string | null reviewed_by?: string } export interface DetectionReviewRead { id?: string | null project_id: string quality_check_id: string analysis_run_id?: string | null evidence_role: DetectionEvidenceRole evidence_feature_id: string detection_id?: string | null reference_feature_id?: string | null decision: DetectionReviewDecision notes?: string | null reviewed_by?: string | null confidence?: number | null class_name?: string | null source_tile_path?: string | null created_at?: string | null updated_at?: string | null } export interface ReviewedScore { matches: number false_positives: number false_negatives: number precision: number | null recall: number | null f1_score: number | null } export interface ReviewedFindingBreakdown { total: number /** Findings the operator established were not the model's error. */ exonerated: number confirmed_or_inconclusive: number unreviewed: number } /** * The score with operator verdicts applied, next to the raw one. A finding * adjudicated as a reference gap is not the model's error; the interval covers * what the unreviewed remainder could still turn out to be. */ export interface ReviewedMetrics { raw: ReviewedScore adjudicated: ReviewedScore pessimistic: ReviewedScore optimistic: ReviewedScore review_complete: boolean false_positive_breakdown: ReviewedFindingBreakdown false_negative_breakdown: ReviewedFindingBreakdown } export interface DetectionReviewSummary { total: number reviewed: number remaining: number false_positive_total: number false_negative_total: number decision_counts: Record reviewed_metrics?: ReviewedMetrics | null } export interface DetectionReviewList { items: DetectionReviewRead[] total: number limit: number offset: number summary: DetectionReviewSummary } export type ExportKind = 'dataset' | 'detection_run' | 'segmentation_run' | 'vector_selection' export interface ExportRead { id: string project_id: string analysis_run_id?: string | null export_type: string storage_path: string metadata_json?: Record | null created_at?: string | null status: string } export interface ExportCreateResponse { export_id: string path: string status: string export_type: string metadata_json?: Record | null } export interface MapResultExportRequest { project_id: string mode: 'current' | 'evolution' bbox: VectorSelectionBBox dataset_id?: string earlier_dataset_id?: string later_dataset_id?: string area_id?: string partitioned?: boolean product_key?: string partition_scope_key?: string theme_id?: string name?: string } export interface ExportListResponse { items: ExportRead[] total: number limit: number offset: number } export interface ExportContentResponse { export_id: string export_type: string content: Record }