openapi: 3.0.3 info: title: Flowfish Platform API description: | # Flowfish Platform API REST API documentation for the eBPF-based Kubernetes/OpenShift application communication and dependency mapping platform. ## Key Features - **Automatic Discovery** — Automatically detect inter-pod communications using eBPF - **Real-Time Dependency Map** — Live visualization of service dependency graphs - **Anomaly Detection** — Intelligent anomaly detection powered by statistical analysis - **Multi-Cluster** — Manage multiple clusters from a single interface - **Integration** — Dependency intelligence APIs for CI/CD pipeline integration - **Pod & Deployment Annotations** — Rich metadata enrichment including annotations merged from owning Deployments/StatefulSets - **Import/Export** — Data import and export in multiple formats ## Authentication The API supports two authentication methods: 1. **JWT (JSON Web Token)** — Send a POST request to `/api/v1/auth/login` with username and password, then include the returned `access_token` in subsequent requests via `Authorization: Bearer ` header. 2. **API Key** — Generate an API key from Settings > API Keys, then include it via `X-API-Key: ` header. Recommended for CI/CD pipelines and AI agent integrations. ## Rate Limiting - **Authenticated Users**: 1,000 requests/hour - **Unauthenticated**: 100 requests/hour version: 1.0.0 contact: name: Flowfish Team email: support@flowfish.io license: name: MIT url: https://opensource.org/licenses/MIT servers: - url: https://api.flowfish.io/api/v1 description: Production server - url: https://staging.flowfish.io/api/v1 description: Staging server - url: http://localhost:8000/api/v1 description: Development server tags: - name: Authentication description: User authentication, JWT token management, and 2FA - name: Users description: User management and profile operations - name: Clusters description: Kubernetes/OpenShift cluster registration, connection, and management - name: Analyses description: Analysis wizard, lifecycle management, and run execution - name: Workloads description: Kubernetes workload inventory (Pod, Deployment, Service, StatefulSet) with labels and annotations - name: Communications description: Service-to-service communication records and dependency graphs - name: Events description: Time-series event queries and aggregations - name: Integration description: Dependency intelligence APIs for CI/CD pipeline integrations — dependency discovery, impact analysis, and cross-project dependency mapping - name: Dependencies description: Dependency map and graph queries - name: Anomalies description: Detected anomalies and outlier events - name: Changes description: Change detection and infrastructure drift tracking - name: Baselines description: Traffic baseline profiles - name: Import/Export description: Data import and export in CSV, JSON, and graph formats - name: Settings description: System configuration and enterprise settings - name: L7 Communications description: Application-layer (HTTP/gRPC/DNS) workload dependency graph from Beyla eBPF — isolated L7Workload graph in Neo4j - name: L7 Events description: L7 HTTP, gRPC, and DNS flow events and histograms from ClickHouse (Beyla-sourced) components: securitySchemes: BearerAuth: type: http scheme: bearer bearerFormat: JWT description: JWT token authorization header using the Bearer scheme schemas: Error: type: object required: - error - message properties: error: type: string example: "UNAUTHORIZED" message: type: string example: "Invalid or expired token" details: type: object nullable: true Pagination: type: object properties: page: type: integer minimum: 1 default: 1 page_size: type: integer minimum: 1 maximum: 100 default: 20 total_items: type: integer total_pages: type: integer User: type: object required: - id - username - email properties: id: type: integer username: type: string email: type: string format: email first_name: type: string nullable: true last_name: type: string nullable: true avatar_url: type: string format: uri nullable: true is_active: type: boolean roles: type: array items: type: string created_at: type: string format: date-time Cluster: type: object required: - id - name - cluster_type properties: id: type: integer name: type: string description: type: string nullable: true cluster_type: type: string enum: [kubernetes, openshift] api_url: type: string format: uri is_active: type: boolean is_default: type: boolean kubernetes_version: type: string nullable: true node_count: type: integer nullable: true pod_count: type: integer nullable: true namespace_count: type: integer nullable: true health_status: type: string enum: [healthy, degraded, unhealthy, unknown] last_sync_at: type: string format: date-time nullable: true created_at: type: string format: date-time Namespace: type: object properties: id: type: integer cluster_id: type: integer name: type: string uid: type: string labels: type: object additionalProperties: type: string status: type: string created_at: type: string format: date-time Workload: type: object properties: id: type: integer cluster_id: type: integer namespace_id: type: integer workload_type: type: string enum: [pod, deployment, statefulset, service] name: type: string labels: type: object additionalProperties: type: string annotations: type: object additionalProperties: type: string ip_address: type: string format: ipv4 nullable: true ports: type: array items: type: object properties: port: type: integer protocol: type: string status: type: string first_seen: type: string format: date-time last_seen: type: string format: date-time is_active: type: boolean Communication: type: object properties: id: type: integer cluster_id: type: integer source_namespace: type: string source_workload: type: string source_workload_type: type: string destination_namespace: type: string destination_workload: type: string destination_workload_type: type: string destination_ip: type: string destination_port: type: integer protocol: type: string first_seen: type: string format: date-time last_seen: type: string format: date-time request_count: type: integer request_rate_per_second: type: number format: float avg_latency_ms: type: number format: float risk_score: type: integer minimum: 0 maximum: 100 risk_level: type: string enum: [low, medium, high, critical] is_cross_namespace: type: boolean is_external: type: boolean is_active: type: boolean Analysis: type: object properties: id: type: integer name: type: string description: type: string cluster_id: type: integer scope_type: type: string enum: [cluster, namespace, deployment, pod, label] scope_config: type: object gadget_modules: type: array items: type: string time_config: type: object output_config: type: object status: type: string enum: [draft, running, stopped, completed, failed] created_at: type: string format: date-time Anomaly: type: object properties: id: type: integer cluster_id: type: integer anomaly_type: type: string severity: type: string enum: [low, medium, high, critical] anomaly_score: type: integer minimum: 0 maximum: 100 title: type: string description: type: string affected_workloads: type: array items: type: object recommended_action: type: string status: type: string enum: [new, investigating, resolved, false_positive] detected_at: type: string format: date-time DependencyStreamCommunication: type: object properties: protocol: type: string app_protocol: type: string service_type: type: string description: Detected service type (e.g. postgresql, kafka, redis) service_category: type: string description: Service category (database, cache, message_broker, search_engine, etc.) enum: [database, cache, message_broker, search_engine, service_discovery, identity, object_storage, observability, api_gateway, mail, dns, file_transfer, service] is_critical: type: boolean description: Whether this dependency is classified as infrastructure-critical port: type: integer request_count: type: integer error_rate_percent: type: number retransmit_count: type: integer avg_latency_ms: type: number DependencyHealth: type: object properties: score: type: integer minimum: 0 maximum: 100 status: type: string enum: [healthy, degraded, unhealthy, critical] error_rate_percent: type: number retransmit_rate_percent: type: number avg_latency_ms: type: number risk_factors: type: array items: type: string DependencyStreamPeer: type: object properties: hop_count: type: integer pod_name: type: string namespace: type: string labels: type: object additionalProperties: type: string annotations: type: object additionalProperties: type: string ip: type: string owner_kind: type: string owner_name: type: string communication: $ref: '#/components/schemas/DependencyStreamCommunication' health: $ref: '#/components/schemas/DependencyHealth' CommunicationsDependenciesBatchRequest: type: object required: - services properties: analysis_id: type: string cluster_id: type: string services: type: array items: type: object properties: pod_name: type: string namespace: type: string owner_name: type: string label_key: type: string label_value: type: string annotation_key: type: string annotation_value: type: string ip: type: string depth: type: integer default: 1 include_communication_details: type: boolean default: true CommunicationsDependenciesBatchResponse: type: object properties: success: type: boolean service_count: type: integer results: type: array items: type: object additionalProperties: true shared_dependencies: type: array items: type: string CommunicationsDependenciesDiffResponse: type: object properties: success: type: boolean service: type: object analysis_before: type: object analysis_after: type: object added_dependencies: type: array items: type: object additionalProperties: true removed_dependencies: type: array items: type: object additionalProperties: true changed_dependencies: type: array items: type: object additionalProperties: true unchanged_count: type: integer summary: type: object CommunicationsDependenciesImpactResponse: type: object properties: success: type: boolean service: type: object dependencies: type: object properties: downstream: type: array items: type: object additionalProperties: true callers: type: array items: type: object additionalProperties: true downstream_count: type: integer callers_count: type: integer impact_assessment: type: object properties: risk_score: type: integer description: Risk score 0-100 risk_level: type: string enum: [low, medium, high, critical] blast_radius: type: integer description: Total direct dependency count critical_dependencies: type: array items: type: string description: List of critical service types (e.g. postgresql, redis) recommendation: type: string enum: [proceed, caution, block] suggested_actions: type: array items: type: object properties: priority: type: string enum: [critical, high, medium, low] action: type: string reason: type: string automatable: type: boolean change_type: type: string enum: [image_update, config_change, scale_change, delete] DependencySummaryService: type: object properties: name: type: string namespace: type: string kind: type: string annotations: type: object additionalProperties: type: string labels: type: object additionalProperties: type: string is_critical: type: boolean service_type: type: string port: type: integer hop_count: type: integer description: Number of hops from the upstream service (1 = direct neighbor). Present when depth > 1. DependencySummaryGroup: type: object properties: total: type: integer critical_count: type: integer by_category: type: object additionalProperties: type: array items: $ref: '#/components/schemas/DependencySummaryService' DependencySummary: type: object properties: total_matched: type: integer description: Number of unique upstream workloads matched total_downstream_unique: type: integer description: Unique downstream dependency count across all matched services total_callers_unique: type: integer description: Unique caller count across all matched services downstream_critical_count: type: integer description: Critical downstream dependency count (globally deduplicated) callers_critical_count: type: integer description: Critical caller count (globally deduplicated) MatchedService: type: object properties: name: type: string namespace: type: string kind: type: string annotations: type: object additionalProperties: type: string labels: type: object additionalProperties: type: string downstream: $ref: '#/components/schemas/DependencySummaryGroup' callers: $ref: '#/components/schemas/DependencySummaryGroup' DependencySummaryResponse: type: object properties: success: type: boolean analysis_ids: type: array items: type: integer multi_service: type: boolean description: True when multiple upstream workloads matched summary: $ref: '#/components/schemas/DependencySummary' service: $ref: '#/components/schemas/DependencySummaryService' description: Aggregate service label. For single match shows actual service info; for multi-match shows summary label. matched_services: type: array description: Each matched upstream workload with its own downstream/callers breakdown. Always present when success is true. items: $ref: '#/components/schemas/MatchedService' error: type: string GraphData: type: object properties: nodes: type: array items: type: object properties: id: type: string type: type: string name: type: string namespace: type: string labels: type: object additionalProperties: type: string annotations: type: object additionalProperties: type: string metadata: type: object edges: type: array items: type: object properties: id: type: string source: type: string target: type: string port: type: integer protocol: type: string metrics: type: object security: - BearerAuth: [] paths: /auth/login: post: tags: - Authentication summary: User login description: Authenticate with username and password to obtain a JWT access token security: [] requestBody: required: true content: application/json: schema: type: object required: - username - password properties: username: type: string password: type: string format: password examples: example1: summary: Admin user value: username: "admin" password: "admin123" responses: '200': description: Login successful content: application/json: schema: type: object properties: access_token: type: string token_type: type: string example: "bearer" expires_in: type: integer example: 3600 user: $ref: '#/components/schemas/User' '401': description: Invalid username or password content: application/json: schema: $ref: '#/components/schemas/Error' /auth/me: get: tags: - Authentication summary: Get current user info description: Returns user information decoded from the JWT token responses: '200': description: User details content: application/json: schema: $ref: '#/components/schemas/User' '401': description: Invalid or missing token content: application/json: schema: $ref: '#/components/schemas/Error' /clusters: get: tags: - Clusters summary: List clusters description: Lists all clusters the authenticated user has access to parameters: - name: page in: query schema: type: integer minimum: 1 default: 1 - name: page_size in: query schema: type: integer minimum: 1 maximum: 100 default: 20 - name: is_active in: query schema: type: boolean responses: '200': description: Cluster list content: application/json: schema: type: object properties: items: type: array items: $ref: '#/components/schemas/Cluster' pagination: $ref: '#/components/schemas/Pagination' post: tags: - Clusters summary: Add new cluster requestBody: required: true content: application/json: schema: type: object required: - name - cluster_type - api_url properties: name: type: string description: type: string cluster_type: type: string enum: [kubernetes, openshift] api_url: type: string format: uri kubeconfig: type: string description: Base64 encoded kubeconfig responses: '201': description: Cluster created successfully content: application/json: schema: $ref: '#/components/schemas/Cluster' '400': description: Invalid request content: application/json: schema: $ref: '#/components/schemas/Error' /clusters/{cluster_id}: get: tags: - Clusters summary: Get cluster details parameters: - name: cluster_id in: path required: true schema: type: integer responses: '200': description: Cluster details content: application/json: schema: $ref: '#/components/schemas/Cluster' '404': description: Cluster not found content: application/json: schema: $ref: '#/components/schemas/Error' put: tags: - Clusters summary: Update cluster parameters: - name: cluster_id in: path required: true schema: type: integer requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: type: string is_active: type: boolean responses: '200': description: Cluster updated content: application/json: schema: $ref: '#/components/schemas/Cluster' delete: tags: - Clusters summary: Delete cluster parameters: - name: cluster_id in: path required: true schema: type: integer responses: '204': description: Cluster deleted '404': description: Cluster not found /analyses: get: tags: - Analyses summary: List analyses parameters: - name: cluster_id in: query schema: type: integer - name: status in: query schema: type: string enum: [draft, running, stopped, completed, failed] responses: '200': description: Analysis list content: application/json: schema: type: object properties: items: type: array items: $ref: '#/components/schemas/Analysis' post: tags: - Analyses summary: Create new analysis description: Defines a new analysis using configuration from the wizard requestBody: required: true content: application/json: schema: type: object required: - name - cluster_id - scope_type - scope_config - gadget_modules - time_config - output_config properties: name: type: string description: type: string cluster_id: type: integer scope_type: type: string enum: [cluster, namespace, deployment, pod, label] scope_config: type: object gadget_modules: type: array items: type: string time_config: type: object properties: mode: type: string enum: [continuous, time_bound, scheduled, baseline] duration_minutes: type: integer schedule: type: string output_config: type: object properties: dashboards: type: array items: type: string llm_enabled: type: boolean alerts_enabled: type: boolean responses: '201': description: Analysis created content: application/json: schema: $ref: '#/components/schemas/Analysis' /analyses/{analysis_id}/start: post: tags: - Analyses summary: Start analysis parameters: - name: analysis_id in: path required: true schema: type: integer responses: '200': description: Analysis started content: application/json: schema: type: object properties: message: type: string run_id: type: integer /analyses/{analysis_id}/stop: post: tags: - Analyses summary: Stop analysis parameters: - name: analysis_id in: path required: true schema: type: integer responses: '200': description: Analysis stopped /workloads: get: tags: - Workloads summary: List workloads parameters: - name: cluster_id in: query required: true schema: type: integer - name: namespace in: query schema: type: string - name: workload_type in: query schema: type: string enum: [pod, deployment, statefulset, service] - name: is_active in: query schema: type: boolean default: true responses: '200': description: Workload list content: application/json: schema: type: object properties: items: type: array items: $ref: '#/components/schemas/Workload' /communications: get: tags: - Communications summary: List communication records parameters: - name: cluster_id in: query required: true schema: type: integer - name: namespace in: query schema: type: string - name: source_workload in: query schema: type: string - name: destination_workload in: query schema: type: string - name: risk_level in: query schema: type: string enum: [low, medium, high, critical] - name: is_active in: query schema: type: boolean default: true - name: from_time in: query schema: type: string format: date-time - name: to_time in: query schema: type: string format: date-time responses: '200': description: Communication records content: application/json: schema: type: object properties: items: type: array items: $ref: '#/components/schemas/Communication' total_count: type: integer /dependencies/graph: get: tags: - Dependencies summary: Get dependency map description: Returns the dependency map as a graph with nodes and edges parameters: - name: cluster_id in: query description: Optional; used for filtering in multi-cluster scenarios schema: type: integer - name: analysis_id in: query schema: type: integer - name: namespace in: query schema: type: string - name: depth in: query schema: type: integer default: 2 - name: search in: query schema: type: string minLength: 3 responses: '200': description: Graph data content: application/json: schema: $ref: '#/components/schemas/GraphData' /events/histogram: get: tags: - Events summary: Event time histogram description: Returns event counts aggregated into time buckets for the given range and filters parameters: - name: cluster_id in: query required: true schema: type: integer - name: analysis_id in: query schema: type: integer - name: event_types in: query schema: type: string description: Comma-separated event type identifiers - name: start_time in: query schema: type: string format: date-time - name: end_time in: query schema: type: string format: date-time - name: bucket_count in: query schema: type: integer minimum: 1 responses: '200': description: Histogram buckets and metadata content: application/json: schema: type: object properties: buckets: type: array items: type: object additionalProperties: true time_range: type: object additionalProperties: true interval_seconds: type: number total_events: type: integer /communications/dependencies/stream: get: tags: - Integration - Communications summary: Get pod dependencies as upstream/downstream description: | Query pod dependencies using any identifying information (annotation, label, pod name, namespace, IP). The matched pod is treated as the upstream service. Pods it communicates with are returned as downstream. Pods that connect to it are returned as callers. Annotations include merged Deployment/StatefulSet metadata. parameters: - name: analysis_id in: query schema: type: integer - name: cluster_id in: query schema: type: integer - name: pod_name in: query schema: type: string - name: namespace in: query schema: type: string - name: owner_name in: query description: Deployment/StatefulSet/DaemonSet name schema: type: string - name: annotation_key in: query description: "Annotation key to match. Supports * wildcard (e.g. mycompany.com/*)" schema: type: string - name: annotation_value in: query description: "Annotation value to match. Supports * wildcard: * for any value, prefix* for startsWith" schema: type: string - name: label_key in: query schema: type: string - name: label_value in: query schema: type: string - name: ip in: query schema: type: string - name: depth in: query description: | Graph traversal depth (1-5 hops). Default 1 returns direct neighbors only. Higher values discover indirect (transitive) dependencies with hop_count metadata. schema: type: integer minimum: 1 maximum: 5 default: 1 - name: format in: query schema: type: string enum: [json, mermaid, dot] default: json responses: '200': description: Upstream pod and its downstream dependencies content: application/json: schema: type: object properties: success: type: boolean count: type: integer results: type: array items: type: object properties: upstream: type: object properties: pod_name: type: string namespace: type: string labels: type: object annotations: type: object ip: type: string owner_kind: type: string owner_name: type: string downstream: type: array items: $ref: '#/components/schemas/DependencyStreamPeer' callers: type: array items: $ref: '#/components/schemas/DependencyStreamPeer' /communications/dependencies/batch: post: tags: - Integration - Communications summary: Batch query dependencies for multiple services requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CommunicationsDependenciesBatchRequest' responses: '200': description: Batch dependency results content: application/json: schema: $ref: '#/components/schemas/CommunicationsDependenciesBatchResponse' /communications/dependencies/diff: get: tags: - Integration - Communications summary: Get dependency diff between two analyses parameters: - name: analysis_id_before in: query required: true schema: type: string - name: analysis_id_after in: query required: true schema: type: string - name: pod_name in: query schema: type: string - name: namespace in: query schema: type: string - name: owner_name in: query schema: type: string - name: cluster_id in: query schema: type: integer responses: '200': description: Dependency diff result content: application/json: schema: $ref: '#/components/schemas/CommunicationsDependenciesDiffResponse' /communications/dependencies/impact: get: tags: - Integration - Communications summary: Dependency impact analysis by change type parameters: - name: analysis_id in: query schema: type: integer - name: cluster_id in: query schema: type: integer - name: pod_name in: query schema: type: string - name: namespace in: query schema: type: string - name: owner_name in: query schema: type: string - name: annotation_key in: query schema: type: string - name: annotation_value in: query schema: type: string - name: label_key in: query schema: type: string - name: label_value in: query schema: type: string - name: ip in: query schema: type: string - name: depth in: query schema: type: integer minimum: 1 maximum: 5 default: 1 - name: change_type in: query schema: type: string enum: [image_update, config_change, scale_change, delete] default: image_update responses: '200': description: Impact analysis result content: application/json: schema: $ref: '#/components/schemas/CommunicationsDependenciesImpactResponse' /communications/dependencies/summary: get: tags: - Integration summary: Per-service dependency summary grouped by category for CI/CD and AI integration description: | Returns a per-service dependency breakdown for CI/CD pipelines, AI agents, and automation. Each matched upstream workload includes its own downstream and callers grouped by service_category. A top-level summary provides globally deduplicated aggregate counts. Dependencies include hop_count when depth > 1 to distinguish direct from indirect paths. Annotations and labels are exposed for cross-project impact analysis (e.g. git-repo URLs, team info). Requires at least one analysis_id and one search parameter. parameters: - name: analysis_ids in: query required: true description: Analysis IDs (at least one required) schema: type: array items: type: integer minItems: 1 - name: cluster_id in: query schema: type: integer - name: pod_name in: query schema: type: string - name: namespace in: query schema: type: string - name: owner_name in: query schema: type: string - name: annotation_key in: query schema: type: string - name: annotation_value in: query schema: type: string - name: label_key in: query schema: type: string - name: label_value in: query schema: type: string - name: ip in: query schema: type: string - name: depth in: query description: | Graph traversal depth (1-5 hops). Default 1 returns direct neighbors only. Higher values discover indirect (transitive) dependencies. Each dependency's hop_count field indicates how many hops it is from the upstream service. schema: type: integer minimum: 1 maximum: 5 default: 1 responses: '200': description: Per-service dependency breakdown with aggregate summary content: application/json: schema: $ref: '#/components/schemas/DependencySummaryResponse' /anomalies: get: tags: - Anomalies summary: List anomalies parameters: - name: cluster_id in: query schema: type: integer - name: severity in: query schema: type: string enum: [low, medium, high, critical] - name: status in: query schema: type: string enum: [new, investigating, resolved, false_positive] - name: from_date in: query schema: type: string format: date responses: '200': description: Anomaly list content: application/json: schema: type: object properties: items: type: array items: $ref: '#/components/schemas/Anomaly' /export/csv: get: tags: - Import/Export summary: Export in CSV format parameters: - name: cluster_id in: query required: true schema: type: integer - name: namespace in: query schema: type: string - name: from_time in: query schema: type: string format: date-time - name: to_time in: query schema: type: string format: date-time responses: '200': description: CSV file content: text/csv: schema: type: string /export/graph-json: get: tags: - Import/Export summary: Export in Graph JSON format parameters: - name: cluster_id in: query required: true schema: type: integer responses: '200': description: Graph JSON file content: application/json: schema: type: object /import: post: tags: - Import/Export summary: Import data requestBody: required: true content: multipart/form-data: schema: type: object required: - file - cluster_id - import_mode properties: file: type: string format: binary cluster_id: type: integer import_mode: type: string enum: [merge, overwrite, snapshot] responses: '202': description: Import job started content: application/json: schema: type: object properties: job_id: type: integer message: type: string # ======================================================================== # L7 Communications (Beyla - Neo4j graph) # ======================================================================== /l7/communications: get: tags: [L7 Communications] summary: List L7 workload-to-workload communications parameters: - name: analysis_id in: query required: true schema: { type: integer } - name: cluster_id in: query schema: { type: integer } - name: namespace in: query schema: { type: string } - name: protocol in: query schema: { type: string, enum: [http, grpc, dns] } - name: limit in: query schema: { type: integer, default: 100 } responses: '200': description: L7 communication list content: application/json: schema: { type: object, additionalProperties: true } /l7/dependencies/graph: get: tags: [L7 Communications] summary: L7 dependency graph (nodes and edges) parameters: - name: analysis_id in: query required: true schema: { type: integer } - name: cluster_id in: query schema: { type: integer } - name: namespace in: query schema: { type: string } - name: protocol in: query schema: { type: string } responses: '200': description: Graph with L7Workload nodes and L7_COMMUNICATES_WITH edges content: application/json: schema: { type: object, additionalProperties: true } /l7/communications/stats: get: tags: [L7 Communications] summary: Aggregated L7 communication statistics parameters: - name: analysis_id in: query required: true schema: { type: integer } - name: cluster_id in: query schema: { type: integer } responses: '200': description: Stats including total workloads, edges, requests, errors, avg latency content: application/json: schema: { type: object, additionalProperties: true } /l7/communications/error-stats: get: tags: [L7 Communications] summary: L7 error totals and breakdown by protocol parameters: - name: analysis_id in: query required: true schema: { type: integer } - name: cluster_id in: query schema: { type: integer } - name: namespace in: query schema: { type: string } responses: '200': description: Error stats per protocol content: application/json: schema: { type: object, additionalProperties: true } /l7/dependencies/summary: get: tags: [L7 Communications] summary: Per-workload L7 dependency summary description: | Returns one entry per L7 workload (Beyla-observed application identity) with aggregated inbound/outbound edge counts, request totals, error totals, and error rate. When any of `annotation_key`, `annotation_value`, `label_key`, `label_value`, `owner_name`, `pod_name`, or `workload_name` is supplied, the response narrows to matched workloads + their immediate neighbours and each workload carries an `is_matched` flag. Glob patterns (`*`, `?`, `[seq]`) are supported on annotation/label key and value fields. `owner_name` is an L4-compatibility alias for `workload_name`. parameters: - name: analysis_id in: query required: true description: Analysis ID; accepts the parent analysis ID or a multi-cluster sub-analysis ID schema: { type: string } - name: cluster_id in: query schema: { type: string } - name: namespace in: query schema: { type: string } - name: include_metadata in: query description: Include labels/annotations/owner_kind on each workload schema: { type: string, default: 'true' } - name: annotation_key in: query description: Filter by annotation key (fnmatch glob supported) schema: { type: string } - name: annotation_value in: query description: Filter by annotation value (fnmatch glob supported; omit for any-value) schema: { type: string } - name: label_key in: query schema: { type: string } - name: label_value in: query schema: { type: string } - name: owner_name in: query description: L4-compatibility alias for `workload_name` schema: { type: string } - name: pod_name in: query description: Case-insensitive substring match against workload name schema: { type: string } - name: workload_name in: query description: Case-insensitive substring match against L7Workload.name schema: { type: string } - name: filter_noise_annotations in: query description: Strip Kubernetes infrastructure annotations from response schema: { type: boolean, default: false } responses: '200': description: Per-workload inbound/outbound/request/error summary content: application/json: schema: { type: object, additionalProperties: true } /l7/dependencies/tree-summary: get: tags: [L7 Communications] summary: L7 dependency tree with downstream/callers grouped by protocol parameters: - name: analysis_id in: query required: true schema: { type: string } - name: cluster_id in: query schema: { type: string } - name: workload_name in: query schema: { type: string } - name: namespace in: query schema: { type: string } - name: depth in: query schema: { type: integer, default: 1, minimum: 1, maximum: 3 } - name: label_key in: query schema: { type: string } - name: label_value in: query schema: { type: string } - name: annotation_key in: query schema: { type: string } - name: annotation_value in: query schema: { type: string } - name: include_metadata in: query schema: { type: string, default: 'true' } - name: workload_name_exact in: query description: | If true (default) match `workload_name` exactly. Pass false for case-insensitive substring match (L4 `owner_name` parity). schema: { type: boolean, default: true } responses: '200': description: Tree-structured dependency summary content: application/json: schema: { type: object, additionalProperties: true } # ======================================================================== # L7 Events (Beyla - ClickHouse time-series) # ======================================================================== /l7/events/http: get: tags: [L7 Events] summary: Query L7 HTTP flow events parameters: - name: analysis_id in: query schema: { type: integer } - name: cluster_id in: query schema: { type: integer } - name: namespace in: query schema: { type: string } - name: method in: query schema: { type: string } - name: path in: query schema: { type: string } - name: status_code in: query schema: { type: integer } - name: start_time in: query schema: { type: string, format: date-time } - name: end_time in: query schema: { type: string, format: date-time } - name: limit in: query schema: { type: integer, default: 100 } - name: offset in: query schema: { type: integer, default: 0 } responses: '200': description: Paginated HTTP flow events content: application/json: schema: { type: object, additionalProperties: true } /l7/events/grpc: get: tags: [L7 Events] summary: Query L7 gRPC flow events parameters: - name: analysis_id in: query schema: { type: integer } - name: cluster_id in: query schema: { type: integer } - name: namespace in: query schema: { type: string } - name: grpc_service in: query schema: { type: string } - name: grpc_method in: query schema: { type: string } - name: grpc_status_code in: query schema: { type: integer } - name: limit in: query schema: { type: integer, default: 100 } - name: offset in: query schema: { type: integer, default: 0 } responses: '200': description: Paginated gRPC flow events content: application/json: schema: { type: object, additionalProperties: true } /l7/events/dns: get: tags: [L7 Events] summary: Query L7 DNS flow events parameters: - name: analysis_id in: query schema: { type: integer } - name: cluster_id in: query schema: { type: integer } - name: namespace in: query schema: { type: string } - name: query_name in: query schema: { type: string } - name: query_type in: query schema: { type: string } - name: response_code in: query schema: { type: integer } - name: limit in: query schema: { type: integer, default: 100 } - name: offset in: query schema: { type: integer, default: 0 } responses: '200': description: Paginated DNS flow events content: application/json: schema: { type: object, additionalProperties: true } /l7/events/stats: get: tags: [L7 Events] summary: Aggregate L7 event statistics across protocols parameters: - name: analysis_id in: query schema: { type: integer } - name: cluster_id in: query schema: { type: integer } - name: namespace in: query schema: { type: string } - name: start_time in: query schema: { type: string, format: date-time } - name: end_time in: query schema: { type: string, format: date-time } responses: '200': description: Per-protocol event counts and totals content: application/json: schema: { type: object, additionalProperties: true } /l7/events/histogram: get: tags: [L7 Events] summary: L7 HTTP request histogram (5-min buckets) parameters: - name: analysis_id in: query schema: { type: integer } - name: cluster_id in: query schema: { type: integer } - name: namespace in: query schema: { type: string } - name: start_time in: query schema: { type: string, format: date-time } - name: end_time in: query schema: { type: string, format: date-time } - name: bucket_count in: query schema: { type: integer, default: 60, minimum: 1, maximum: 200 } responses: '200': description: Time-bucketed request counts with error rates content: application/json: schema: { type: object, additionalProperties: true }