openapi: 3.2.0 info: title: Fenergo Nebula Business Metrics Query Agent Value Story API description: '**Business Metrics Query API**: Business Metrics Query API provides endpoints in order to retrieve all related models and their versions. **Business Metrics Query API provides**:' version: '1.0' servers: - url: /businessmetricsquery security: - Bearer: [] tags: - name: AgentValueStory paths: /api/agent-value-story: get: tags: - AgentValueStory summary: Get the composite agent value story for a date range description: 'Returns per-agent action counts, derived hours/cost savings, hero KPIs, platform screening telemetry, journey type counts, and a monthly time-series for the requested date range. Aggregates data from DigitalAgents, Redshift, and DynamoDB tenant assumptions in a single call. Tier 3 fields (entityOverview, transactionAlerts) are returned as pendingIntegration: true placeholders until stories 541085 and 541086 land. Required permissions: Following permissions are required: ValueStoryAccess' operationId: GetAgentValueStory parameters: - name: from in: query description: The inclusive start date (ISO 8601, e.g. 2026-01-01). schema: type: string format: date - name: to in: query description: The inclusive end date (ISO 8601, e.g. 2026-01-31). schema: type: string format: date - name: X-TENANT-ID in: header description: The UiD of the tenant representing organization required: true schema: type: string example: b11f8be3-f29b-4959-8964-956d4af7c468 responses: '200': description: Success. Returns the composite agent value story. content: text/plain: schema: $ref: '#/components/schemas/AgentValueStoryResponseDtoServiceResponse' application/json: schema: $ref: '#/components/schemas/AgentValueStoryResponseDtoServiceResponse' text/json: schema: $ref: '#/components/schemas/AgentValueStoryResponseDtoServiceResponse' '400': description: Invalid date parameters (missing, unparseable, from > to, or range > 24 months). content: text/plain: schema: $ref: '#/components/schemas/ServiceResponse' application/json: schema: $ref: '#/components/schemas/ServiceResponse' text/json: schema: $ref: '#/components/schemas/ServiceResponse' '500': description: Internal error or upstream failure. content: text/plain: schema: $ref: '#/components/schemas/ServiceResponse' application/json: schema: $ref: '#/components/schemas/ServiceResponse' text/json: schema: $ref: '#/components/schemas/ServiceResponse' '401': description: User is not authorized to perform this request content: application/json: example: message: Unauthorized '403': description: Access to resource is forbidden. content: application/json: schema: $ref: '#/components/schemas/ObjectServiceResponse' example: data: {} messages: - message: 'Access denied. Following permissions are required: Permission1, Permission2' type: Forbidden errorCode: Error Code '410': description: Endpoint marked as deprecated was terminated. This response will be present only if the endpoint was marked as deprecated and has reached the sunset date. During the deprecation period, the API will include additional 'sunset' and 'deprecation' headers. content: application/json: schema: $ref: '#/components/schemas/StringServiceResponse' example: data: null messages: - message: This endpoint is obsolete and was terminated on yyyy-MM-dd type: Error errorCode: OBSOLETE_ENDPOINT components: schemas: AgentValueStoryResponseDto: type: object properties: from: type: string description: Gets or sets the start of the requested date range (inclusive). format: date to: type: string description: Gets or sets the end of the requested date range (inclusive). format: date heroKpis: allOf: - $ref: '#/components/schemas/HeroKpisDto' description: Gets or sets the aggregate hero KPIs for the date range. agentSummaries: allOf: - $ref: '#/components/schemas/AgentSummariesDto' description: Gets or sets the per-agent action counts and derived savings. platformTelemetry: allOf: - $ref: '#/components/schemas/PlatformTelemetryDto' description: Gets or sets the platform screening and journey telemetry. monthlySeries: type: - array - 'null' items: $ref: '#/components/schemas/MonthlyBucketDto' description: Gets or sets the monthly time-series of agent metrics and cumulative cost saved. entityOverview: allOf: - $ref: '#/components/schemas/PendingIntegrationDto' description: 'Gets or sets the entity overview section. Wired to real data (Story 541085''s entity/related-party count queries) since Story 545286 — Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.PendingIntegrationDto.PendingIntegration is `false` and Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.PendingIntegrationDto.Data carries an Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.EntityOverviewDto.' transactionAlerts: allOf: - $ref: '#/components/schemas/PendingIntegrationDto' description: 'Gets or sets the transaction alerts section. Wired to real data (Story 543478''s transaction-alert count query) since Story 545286 — Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.PendingIntegrationDto.PendingIntegration is `false` and Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.PendingIntegrationDto.Data carries a Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.RiskDistributionDto.' assumptions: allOf: - $ref: '#/components/schemas/AssumptionsSummaryDto' description: Gets or sets the assumptions used to derive all ROI figures in this response. executiveSummary: allOf: - $ref: '#/components/schemas/ExecutiveSummaryDto' description: Gets or sets the Executive Summary section (narrative + payback period). capacity: allOf: - $ref: '#/components/schemas/CapacityDto' description: Gets or sets the Capacity gauge section (full-contract-year baseline). platformTab: allOf: - $ref: '#/components/schemas/PlatformTabDto' description: Gets or sets the Platform tab content. agentsTab: allOf: - $ref: '#/components/schemas/AgentsTabDto' description: Gets or sets the Agents tab content. operations: allOf: - $ref: '#/components/schemas/PendingIntegrationDto' description: 'Gets or sets the Operations tab content. Since Story 546092, wraps Agreement by Decision Category + Intervention Volume/Agreement Rate trend (Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.OperationsTabDto) once the DigitalAgents Trust-table fields are present; `{ pendingIntegration: true }` until then, or if a DigitalAgents deploy lag means only one of the two upstream fields is populated. HAI review-time/override-reasons (546093) and QA Findings (546094) remain pending.' additionalProperties: false description: 'Composite response for the agent value story endpoint. Aggregates per-agent action counts, derived ROI KPIs, platform telemetry, and monthly time-series data.' JourneysByTypeDto: type: object properties: onboarding: type: integer description: Gets the count of completed "Client Onboarding" journeys. format: int32 periodicReview: type: integer description: Gets the count of completed "Periodic Review" journeys. format: int32 maintenance: type: integer description: Gets the count of completed "Maintenance" journeys. format: int32 additionalProperties: false description: 'Journey counts grouped into the three canonical onboarding journey types. Journey types outside these three buckets are dropped by design.' CapacityOverageStatusDto: enum: - Ok - Warn80 - Warn90 - Over100 type: string description: 'Wire-contract mirror of Fenergo.Nebula.BusinessMetrics.Domain.Models.Assumptions.CapacityOverageStatus (AB#550218 position 7). A dedicated Query.Application enum rather than exposing the Domain enum directly on Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.CapacityDto — this DTO layer never re-exposes Domain types verbatim on the wire (see `AssumptionsSummaryDto`/`QaFindingDto`, which mirror rather than reuse their Domain counterparts), so the JSON contract''s numeric ordinals/names stay independent of the internal Domain enum''s own evolution. Purely informational — overage never blocks anything.' KpiTileGridDto: type: object properties: autonomousResolution: allOf: - $ref: '#/components/schemas/KpiTileDto' description: Gets the Autonomous Resolution tile — journey-completion agentic %. dataPointsExtracted: allOf: - $ref: '#/components/schemas/KpiTileDto' description: Gets the Data Points Extracted tile. Pending — no data source today. documentsClassified: allOf: - $ref: '#/components/schemas/KpiTileDto' description: Gets the Documents Classified tile. screeningAutonomous: allOf: - $ref: '#/components/schemas/KpiTileDto' description: Gets the Screening Autonomous tile — resolved (match or clean) % of total detections. monitoringAutonomous: allOf: - $ref: '#/components/schemas/KpiTileDto' description: Gets the Monitoring Autonomous tile. Pending — no data source today. additionalProperties: false description: 'The Platform tab''s 5-tile KPI grid. "Data Points Extracted" and "Monitoring Autonomous" ship with Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.KpiTileDto.PendingIntegration`true` — no data source exists for either today (see plans/546091-platform-kpi-case-throughput.plan.md, Open Question 1).' HeroKpisDto: type: object properties: totalHoursSaved: type: number description: Gets the total analyst hours saved across all agents over the date range. format: double totalCostSaved: type: number description: Gets the total estimated cost saved across all agents over the date range. format: double fteEquivalent: type: number description: 'Gets the full-time employee equivalent saved. Computed as totalHoursSaved / (productiveHoursPerMonth * monthsInRange).' format: double risksDetected: type: integer description: 'Gets the number of confirmed positive screening matches (risksDetected). Derived from ScreeningMatchCount — not ScreeningDetectionsTotal, which would overstate risk by including no-match and unresolved outcomes.' format: int32 additionalProperties: false description: Aggregate hero KPI card displayed at the top of the agent value story dashboard. AgentSummariesDto: type: object properties: docsClassifier: allOf: - $ref: '#/components/schemas/AgentSummaryDto' description: Gets the document classification agent summary. hitsAutoResolver: allOf: - $ref: '#/components/schemas/AgentSummaryDto' description: Gets the screening auto-resolution agent summary. suggestionsAcceptance: allOf: - $ref: '#/components/schemas/AgentSummaryDto' description: Gets the AI suggestions acceptance agent summary. reportsGenerator: allOf: - $ref: '#/components/schemas/AgentSummaryDto' description: Gets the AI report generation agent summary. sourcesRetriever: allOf: - $ref: '#/components/schemas/AgentSummaryDto' description: Gets the data source retrieval agent summary. policyChecker: allOf: - $ref: '#/components/schemas/AgentSummaryDto' description: Gets the policy check execution agent summary. signal: type: integer description: 'Gets the Kyra:Signal agent''s raw action count for the requested range. Deliberately carries only the action count, not derived hours/cost — the client recomputes those from the tenant''s live `SignalMinutes` assumption via the Assumptions API, so a server-computed hours/cost figure here would be the one field on the page not reactive to a live Edit Assumptions drawer change.' format: int32 signalAccuracyRate: type: - number - 'null' description: 'Gets KYRA:Signal''s accuracy proxy for the requested range (AB#547423): `100 - SignalUndeterminedRate` — the rate of runs that reached a confident Significant/Insignificant verdict rather than Undetermined. Null when no Significance activity occurred this period. A sibling field to Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.AgentSummariesDto.Signal, not a change to its type — see Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.AgentSummariesDto.Signal''s own doc comment for why that stays a plain `int`.' format: double signalTrend: type: - string - 'null' description: Gets KYRA:Signal's accuracy trend vs the prior equivalent period (AB#547471). Same "up"/"down"/"flat"/null convention as Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.AgentSummaryDto.Trend. signalPriorPeriodCount: type: integer description: Gets KYRA:Signal's real action count for the prior equivalent period (AB#547471). format: int32 additionalProperties: false description: 'Container for all six per-agent summaries. Fixed-shape properties (not a dictionary) give the UI compile-time contracts and avoid string-keyed access.' ExecutiveSummaryDto: type: object properties: headline: type: - string - 'null' description: Gets the short headline for the Executive Summary card. narrative: type: - string - 'null' description: 'Gets the deterministic narrative composed from the requested range''s hero KPIs (top-saving agent, total hours/cost saved, FTE equivalent, risks detected, journey volume). No upstream text-generation call is involved.' paybackPeriodMonths: type: - number - 'null' description: 'Gets the payback period, in months, for the tenant''s annual subscription cost. `null` when the tenant has not set `AnnualSubscriptionCost`, or when there is no positive cost saved to amortise it against.' format: double additionalProperties: false description: 'Executive Summary section: a deterministic, server-composed narrative and headline built from the already-computed hero KPIs, plus an optional payback-period figure.' PlatformTelemetryDto: type: object properties: screeningDetections: allOf: - $ref: '#/components/schemas/ScreeningDetectionsDto' description: Gets the screening detection counts. entitiesScreened: type: integer description: 'Gets the total number of entities screened. Derived as ScreeningMatchCount + ScreeningNoMatchCount + ScreeningUnresolvedCount. Every screened entity yields exactly one of the three outcomes, so this numerically equals ScreeningDetectionsTotal.' format: int32 hitRatePercent: type: number description: 'Gets the screening hit rate as a percentage. Computed as (ScreeningMatchCount / entitiesScreened * 100), rounded to 2 decimal places. Returns 0 when entitiesScreened is 0 to avoid divide-by-zero.' format: double autoResolved: type: integer description: 'Gets the number of screening hits auto-resolved. Passthrough of HitsAutoResolved from DigitalAgents.' format: int32 journeysByType: allOf: - $ref: '#/components/schemas/JourneysByTypeDto' description: Gets the journey completion counts grouped by type. additionalProperties: false description: 'Platform telemetry section of the agent value story: screening detection outcomes, entity screening counts, hit rate, auto-resolution count, and journey type breakdown.' CapacityAgentCreditsDto: type: object properties: agentKey: type: - string - 'null' description: 'The canonical agent key (see `Domain.Models.Assumptions.CapacityMeasureCatalog`), e.g. `kyra_docs`. Same identifier space as `AgentActivations` on `GetTenantAssumptionsResponseDto` (RD-4) — a client can join the two by this key.' isMetered: type: boolean description: '`false` when every measure this agent owns is unmetered (Guardrail §6).' creditsConsumed: type: - number - 'null' description: Total credits consumed by this agent across all its measures. `null`, never `0`, when Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.CapacityAgentCreditsDto.IsMetered is `false`. format: double activationDate: type: - string - 'null' description: The activation date used for this agent's projection (per-agent, falling back to the tenant-level date). `null` if neither is available. format: date projectedAnnualCredits: type: - number - 'null' description: Burn-rate-per-day × 365 (RD-5). `null` when the agent is unmetered or has no resolvable activation date. format: double eventSubCounts: type: - array - 'null' items: $ref: '#/components/schemas/CapacityMeasureCreditDto' description: This agent's measures, rolled up into display groups (Kyra:Docs combines two sub-events into one "Docs" entry here; every other agent has exactly one entry, matching its own single measure). additionalProperties: false description: 'One Kyra agent''s capacity-credit detail (AB#550218 D1) — credits consumed, activation-aware projection, and per-event-type sub-counts. Mirrors Fenergo.Nebula.BusinessMetrics.Domain.Models.Assumptions.CapacityAgentConsumptionResult. Kyra:Docs'' classification + extraction sub-events are already combined into a single "kyra_docs" entry''s Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.CapacityAgentCreditsDto.EventSubCounts (Guardrail §7) via the agent-key grouping `GetAgentValueStoryMapper`''s `BuildCapacity` applies, rather than appearing as two separate agent entries.' PlatformTabDto: type: object properties: aiSummary: type: - string - 'null' description: Gets the deterministic, server-composed operational summary for the Platform tab. kpiGrid: allOf: - $ref: '#/components/schemas/KpiTileGridDto' description: Gets the 5-tile KPI grid (Autonomous Resolution, Data Points Extracted, Documents Classified, Screening Autonomous, Monitoring Autonomous). caseThroughput: allOf: - $ref: '#/components/schemas/CaseThroughputDto' description: Gets the case throughput breakdown, including autonomous-vs-human-assisted splits and the daily-bucketed series. dataCompleteness: allOf: - $ref: '#/components/schemas/PendingIntegrationDto' description: 'Gets the data completeness payload — real agentic-% headline data plus a per-journey-type agentic-vs-human breakdown, sourced from `JourneyCompletedElapsedTimeDaily.NumAutocompleted`. Always `{ pendingIntegration: false, data: DataCompletenessDto }`.' slaCompliance: allOf: - $ref: '#/components/schemas/PendingIntegrationDto' description: 'Gets the SLA compliance payload — real per-journey-type actual-vs-target compliance plus an overall percentage, sourced from `JourneyCompletedElapsedTimeDaily.NumSlaMet`/ `NumSlaEligible` and the tenant''s configured SLA targets. Always `{ pendingIntegration: false, data: SlaComplianceDto }`.' riskDistribution: allOf: - $ref: '#/components/schemas/RiskDistributionDto' description: Gets the transaction-alert risk distribution for the date range. additionalProperties: false description: 'Platform tab content: an AI-composed operational summary, the 5-tile KPI grid, case throughput, transaction-alert risk distribution, real data-completeness (agentic %), and real SLA compliance.' ScreeningDispositionDto: type: object properties: match: type: integer description: Gets the number of confirmed positive screening matches. format: int32 noMatch: type: integer description: Gets the number of screening no-match outcomes. format: int32 unresolved: type: integer description: Gets the number of unresolved screening outcomes. format: int32 additionalProperties: false description: 'Screening outcome disposition for the Agents tab — echoes the three DigitalAgents screening-outcome fields (`ScreeningMatchCount`/`ScreeningNoMatchCount`/ `ScreeningUnresolvedCount` on `AgentValueSummaryResponseDto`) already surfaced elsewhere in this response.' ServiceResponse: type: object properties: data: type: - string - 'null' messages: type: - array - 'null' items: $ref: '#/components/schemas/ServiceResponseMessage' additionalProperties: false AgentSummaryDto: type: object properties: actionCount: type: integer description: Gets the raw action count for this agent over the date range. format: int32 hoursSaved: type: number description: Gets the hours of analyst time saved by this agent (actionCount * minutesPerAction / 60). format: double costSaved: type: number description: Gets the estimated cost saved by this agent (hoursSaved * hourlyRate). format: double minutesPerAction: type: integer description: Gets the per-action minutes assumption used to derive hours saved (echoed from assumptions). format: int32 accuracy: type: - number - 'null' description: 'Gets this agent''s accuracy % for the requested range (AB#547423). Null where no accuracy signal exists for this agent (Suggestions/Reports/Policy) — not a manufactured 0%.' format: double avgConfidencePct: type: - number - 'null' description: 'Gets this agent''s confidence score — the rounded Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.AgentSummaryDto.Accuracy value, per AB#547429''s resolution ("not a new metric... rounded per-agent accuracy value"). Null when Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.AgentSummaryDto.Accuracy is null.' format: double trend: type: - string - 'null' description: 'Gets this agent''s accuracy trend vs the prior equivalent period (AB#547471): "up" | "down" | "flat", or null when no accuracy signal exists for this agent (same agents as Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.AgentSummaryDto.Accuracy null).' priorPeriodCount: type: integer description: Gets this agent's real action count for the prior equivalent period (AB#547471) — replaces the previous fabricated ×0.88 placeholder. format: int32 additionalProperties: false description: Per-agent action counts plus the derived hours and cost saved for the requested date range. RiskDistributionDto: type: object properties: total: type: integer description: Gets the total number of transaction alerts raised over the date range. format: int32 high: type: integer description: Gets the number of alerts scoring at or above the tenant's high-score threshold. format: int32 medium: type: integer description: Gets the number of alerts scoring at or above the medium threshold but below the high threshold. format: int32 low: type: integer description: Gets the number of alerts scoring below the tenant's medium-score threshold. format: int32 additionalProperties: false description: 'Transaction-alert risk distribution, bucketed by tenant-configured score thresholds. One-to-one echo of `GetTransactionAlertCountsByDateRangeResponseDto` (`Fenergo.Nebula.BusinessMetrics.Query.Application.Features.GetTransactionAlertCountsByDateRange`), re-declared locally so the agent-value-story response surface does not cross-reference another feature''s response DTO directly.' AgentsTabDto: type: object properties: subAgents: allOf: - $ref: '#/components/schemas/AgentSummariesDto' description: Gets the sub-agent summaries — the same object graph as the top-level `AgentSummaries`. docClassificationBreakdown: allOf: - $ref: '#/components/schemas/PendingIntegrationDto' description: 'Gets the doc classification breakdown, sourced from DigitalAgents'' `agent-value-summary``DocsClassifiedByType` field, ordered by count descending then type ascending (ordinal, case-insensitive). `{ pendingIntegration: false, data: [{ type, count }] }` once the upstream DigitalAgents response includes the field — `data` is an empty list, not a pending placeholder, when the requested range genuinely has no classifications. `{ pendingIntegration: true }` only when the upstream response omits the field entirely (predates DigitalAgents PR #564 in this environment) — this is distinguishable from a genuine zero because the client DTO''s `DocsClassifiedByType` is nullable with no default.' screeningDisposition: allOf: - $ref: '#/components/schemas/ScreeningDispositionDto' description: Gets the screening outcome disposition (match/no-match/unresolved) for the date range. aiSummary: type: - string - 'null' description: Gets the deterministic, server-composed operational summary for the Agents tab. additionalProperties: false description: 'Agents tab content: the shared sub-agent summary table, screening disposition breakdown, and the per-document-type classification breakdown.' DailyJourneyCountDto: type: object properties: date: type: string description: Gets the calendar date this count applies to. format: date journeyType: type: - string - 'null' description: Gets the journey type this count applies to (e.g. "Client Onboarding"). count: type: integer description: Gets the number of journeys of this type completed on this date. format: int32 autonomousCount: type: integer description: 'Gets the number of journeys of this type completed autonomously (no human review) on this date. Invariant: `Count == AutonomousCount + HumanAssistedCount`.' format: int32 humanAssistedCount: type: integer description: Gets the number of journeys of this type completed with human assistance on this date. format: int32 additionalProperties: false description: 'A single day''s completed-journey count for one journey type, used to build the Platform tab''s Case Throughput daily series.' CapacityAgentActionCountsDto: type: object properties: docsClassifier: type: integer description: Gets the document classification agent's action count. format: int32 hitsAutoResolver: type: integer description: Gets the screening auto-resolution agent's action count. format: int32 suggestionsAcceptance: type: integer description: Gets the AI suggestions acceptance agent's action count. format: int32 reportsGenerator: type: integer description: Gets the AI report generation agent's action count. format: int32 sourcesRetriever: type: integer description: Gets the data source retrieval agent's action count. format: int32 policyChecker: type: integer description: Gets the policy check execution agent's action count. format: int32 extraction: type: integer description: 'Gets the Kyra:Docs data-field-extraction agent''s action count (AB#547917). Same raw-count, no-server-side-derivation contract as Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.CapacityAgentActionCountsDto.Signal — hours/cost/credits stay client-computed downstream; the server does not multiply this by any credit rate.' format: int32 signal: type: integer description: 'Gets the Kyra:Signal agent''s action count. Unlike the other six, Signal''s hours/cost are never derived server-side anywhere on this page (see Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.AgentSummariesDto.Signal''s doc comment) — this raw count exists solely so the client''s Capacity gauge can compute Signal''s contribution from the live `signalMinutes` assumption, same as the other six.' format: int32 agentCredits: type: - array - 'null' items: $ref: '#/components/schemas/CapacityAgentCreditsDto' description: 'Gets each Kyra agent''s capacity-credit detail (AB#550218 D1) — one entry per agent key in `Domain.Models.Assumptions.CapacityMeasureCatalog`, NOT a 1:1 map with the 8 flat raw- count fields above: Kyra:Docs'' classification + extraction combine into a single "kyra_docs" entry here (Guardrail §7), so this list can have fewer entries than distinct measures. `BuildCapacity` always enumerates `CapacityMeasureCatalog.CreditMeasureMap` and populates one entry per agent key regardless of whether the optional credit inputs (rate table, ledger, activations) were supplied — an agent with no resolvable rate/data appears here with `IsMetered = false` and a `null` (never `0`) `CreditsConsumed`, per Guardrail §6''s "not metered, never 0%" contract; the list itself is not empty in that case (Copilot review, AB#550218 PR #802 — corrected from an earlier, inaccurate "empty when no credit inputs supplied" doc). Additive, never removes or repurposes the raw-count fields above (Guardrail §1).' additionalProperties: false description: 'Per-agent raw action counts over the Capacity gauge''s full-contract-year window. Deliberately carries only action counts, not derived hours/cost — the client recomputes those from the live per-agent minutes assumption, so a server-computed figure here would be the one stat on the page that goes stale when the Assumptions drawer is edited.' KpiTileDto: type: object properties: eyebrow: type: - string - 'null' description: Gets the tile's eyebrow label (e.g. "This period"). value: type: - number - 'null' description: Gets the tile's primary value. `null` when Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.KpiTileDto.PendingIntegration is `true`. format: double subLabel: type: - string - 'null' description: Gets the tile's sub-label (e.g. "documents", "% autonomous"). deltaPercent: type: - number - 'null' description: 'Gets the within-range delta percent — first-vs-last-month of the monthly series. `null` when fewer than two monthly buckets exist, or when Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.KpiTileDto.PendingIntegration is `true`.' format: double sparkline: type: - array - 'null' items: type: number format: double description: Gets the monthly sparkline points. Empty when Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.KpiTileDto.PendingIntegration is `true`. pendingIntegration: type: boolean description: 'Gets a value indicating whether this tile has no data source today. When `true`, Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.KpiTileDto.Value, Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.KpiTileDto.DeltaPercent are `null` and Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.KpiTileDto.Sparkline is empty.' additionalProperties: false description: 'A single tile in the Platform tab''s KPI grid: eyebrow label, headline value, a within-range delta, a sub-label, and a monthly sparkline. Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.KpiTileDto.Value, Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.KpiTileDto.DeltaPercent, and Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.KpiTileDto.Sparkline stay unset when Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.KpiTileDto.PendingIntegration is `true` — the tile has no data source today (see "Data Points Extracted" / "Monitoring Autonomous").' PendingIntegrationDto: type: object properties: pendingIntegration: type: boolean description: Gets a value indicating whether the integration for this section is pending. data: description: Gets the data payload. Always `null` while Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.PendingIntegrationDto.PendingIntegration is `true`. additionalProperties: false description: 'Placeholder shape for Tier 3 fields whose upstream integrations are not yet wired. Used for entityOverview (Story 541085) and transactionAlerts (Story 541086).' AgentValueStoryResponseDtoServiceResponse: type: object properties: data: allOf: - $ref: '#/components/schemas/AgentValueStoryResponseDto' description: 'Composite response for the agent value story endpoint. Aggregates per-agent action counts, derived ROI KPIs, platform telemetry, and monthly time-series data.' messages: type: - array - 'null' items: $ref: '#/components/schemas/ServiceResponseMessage' additionalProperties: false ObjectServiceResponse: type: object properties: data: {} messages: type: - array - 'null' items: $ref: '#/components/schemas/ServiceResponseMessage' additionalProperties: false CaseThroughputDto: type: object properties: onboarding: type: integer description: Gets the number of Client Onboarding journeys completed over the date range. format: int32 onboardingAutonomous: type: integer description: 'Gets the number of Client Onboarding journeys completed autonomously (no human review). Invariant: `Onboarding == OnboardingAutonomous + OnboardingHumanAssisted`.' format: int32 onboardingHumanAssisted: type: integer description: Gets the number of Client Onboarding journeys completed with human assistance. format: int32 periodicReview: type: integer description: Gets the number of Periodic Review journeys completed over the date range. format: int32 periodicReviewAutonomous: type: integer description: 'Gets the number of Periodic Review journeys completed autonomously (no human review). Invariant: `PeriodicReview == PeriodicReviewAutonomous + PeriodicReviewHumanAssisted`.' format: int32 periodicReviewHumanAssisted: type: integer description: Gets the number of Periodic Review journeys completed with human assistance. format: int32 maintenance: type: integer description: Gets the number of Maintenance journeys completed over the date range. format: int32 maintenanceAutonomous: type: integer description: 'Gets the number of Maintenance journeys completed autonomously (no human review). Invariant: `Maintenance == MaintenanceAutonomous + MaintenanceHumanAssisted`.' format: int32 maintenanceHumanAssisted: type: integer description: Gets the number of Maintenance journeys completed with human assistance. format: int32 dailyCounts: type: - array - 'null' items: $ref: '#/components/schemas/DailyJourneyCountDto' description: Gets the daily-bucketed journey completion counts, by date and journey type. additionalProperties: false description: 'Case throughput section of the Platform tab: journey completion counts by type over the requested range, plus a daily-bucketed breakdown for trend charts.' MonthlyBucketDto: type: object properties: month: type: - string - 'null' description: Gets the month in "yyyy-MM" format. docsClassified: type: integer description: Gets the number of documents classified in this month. format: int32 hitsAutoResolved: type: integer description: Gets the number of screening hits auto-resolved in this month. format: int32 suggestionsAccepted: type: integer description: Gets the number of AI suggestions accepted in this month. format: int32 reportsGenerated: type: integer description: Gets the number of AI-generated reports in this month. format: int32 sourcesRetrieved: type: integer description: Gets the number of data sources retrieved in this month. format: int32 policyChecksRun: type: integer description: Gets the number of policy checks run in this month. format: int32 signal: type: integer description: Gets the number of Kyra:Signal checks run in this month. format: int32 totalHoursSaved: type: number description: Gets the total analyst hours saved across all agents in this month. format: double cumulativeCostSaved: type: number description: Gets the running cumulative cost saved from the start of the range up to and including this month. format: double additionalProperties: false description: 'Per-month bucket in the monthly time-series of the agent value story. Contains per-agent action counts, total hours saved for the month, and a running cumulative cost saved up to and including this month.' StringServiceResponse: type: object properties: data: type: - string - 'null' messages: type: - array - 'null' items: $ref: '#/components/schemas/ServiceResponseMessage' additionalProperties: false AssumptionsSummaryDto: type: object properties: hourlyRate: type: number description: Gets the analyst hourly rate used for cost derivations. format: double docMinutes: type: integer description: Gets the minutes-per-action assumption for document classification. format: int32 autoMinutes: type: integer description: Gets the minutes-per-action assumption for screening auto-resolution. format: int32 signalMinutes: type: integer description: Gets the minutes-per-action assumption for AI signal/suggestion acceptance. format: int32 reportMinutes: type: integer description: Gets the minutes-per-action assumption for report generation. format: int32 sourceMinutes: type: integer description: Gets the minutes-per-action assumption for data source retrieval. format: int32 policyMinutes: type: integer description: Gets the minutes-per-action assumption for policy checks. format: int32 productiveHoursPerMonth: type: integer description: Gets the productive hours per month assumption used in the FTE equivalent calculation. format: int32 isUsingDefaults: type: boolean description: 'Gets a value indicating whether system defaults were used because no tenant-specific assumptions have been saved.' additionalProperties: false description: 'An echo of the ROI assumptions used to derive the agent value story figures. Included in the response so the UI can render "why" tooltips without a second call to the assumptions endpoint.' CapacityDto: type: object properties: annualHoursAllotment: type: integer description: Gets the tenant's annual hours allotment. `0` means unset — the UI hides the Capacity gauge. format: int32 hoursSavedFullYear: type: number description: Gets the total hours saved across all agents over the full contract year. format: double fullYearFrom: type: string description: Gets the inclusive start date of the full-contract-year window. format: date fullYearTo: type: string description: Gets the inclusive end date of the full-contract-year window (the request's `to` date). format: date utilizationPercent: type: - number - 'null' description: 'Gets the utilization percentage (`HoursSavedFullYear / AnnualHoursAllotment * 100`, rounded to 2 decimal places). `null` when Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.CapacityDto.AnnualHoursAllotment is `0`.' format: double agentBreakdown: allOf: - $ref: '#/components/schemas/CapacityAgentActionCountsDto' description: 'Gets the per-agent raw action counts over the same full-contract-year window as Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.CapacityDto.HoursSavedFullYear. Summing each agent''s action count times the tenant''s current stored per-agent minutes assumption reconciles with Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.CapacityDto.HoursSavedFullYear.' capacityUnitsPurchased: type: integer description: 'Gets the tenant''s purchased annual entitlement, in capacity credits (`assumptions.AnnualVolumeCredits`, RD-6). Always sourced from the tenant''s assumptions regardless of whether the optional credit inputs (rate table, ledger, activations) were supplied to `BuildCapacity` — those inputs affect Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.CapacityDto.CapacityUnitsConsumed/projection, not the entitlement itself. A brand-new tenant''s default `AnnualVolumeCredits` (the Launch band floor, 2,000,000) means this is effectively never `0` in practice (Copilot review, AB#550218 PR #802 — corrected from an earlier, inaccurate "0 when no credit inputs supplied" doc).' format: int64 capacityUnitsConsumed: type: number description: Gets the total capacity credits consumed (closed-period frozen ledger sum + open-period live calculation, RD-1). format: double capacityUnitsRemaining: type: number description: 'Gets Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.CapacityDto.CapacityUnitsPurchased minus Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.CapacityDto.CapacityUnitsConsumed. Deliberately NOT clamped at zero — a negative value is the overage signal (position 7: overage never blocks, so it must remain visible, not be hidden by clamping).' format: double percentConsumed: type: - number - 'null' description: Gets Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.CapacityDto.CapacityUnitsConsumed ÷ Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.CapacityDto.CapacityUnitsPurchased × 100. `null` only when Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.CapacityDto.CapacityUnitsPurchased is `<= 0` (defensive). format: double percentProjected: type: - number - 'null' description: Gets the projected full-year consumption (sum of each agent's activation-aware burn-rate × 365, RD-5) as a percentage of Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.CapacityDto.CapacityUnitsPurchased. `null` under the same condition as Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.CapacityDto.PercentConsumed. format: double bandName: type: - string - 'null' description: Gets the name of the capacity band Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.CapacityDto.CapacityUnitsPurchased resolves to (e.g. "Launch"). `null` when no band-reference data was supplied. entitlementPeriodStart: type: - string - 'null' description: Gets the inclusive start date of the tenant's current commercial capacity/entitlement period (the tenant's `ActivationDate`, RD-6). `null` when the tenant has never been activated. format: date entitlementPeriodEnd: type: - string - 'null' description: Gets the exclusive end date of the tenant's current commercial capacity/entitlement period (Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.CapacityDto.EntitlementPeriodStart + 1 year). `null` when Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.CapacityDto.EntitlementPeriodStart is `null`. format: date overageStatus: allOf: - $ref: '#/components/schemas/CapacityOverageStatusDto' description: Gets the consumed-vs-purchased overage/warning band (position 7 — never blocks, purely informational). additionalProperties: false description: 'Capacity gauge section: full-contract-year (rolling 12 months back from the requested `to` date) baseline hours saved against the tenant''s annual hours allotment.' ScreeningDetectionsDto: type: object properties: total: type: integer description: 'Gets the total number of screening detections (ScreeningMatchCount + ScreeningNoMatchCount + ScreeningUnresolvedCount).' format: int32 sanctions: type: integer description: 'Gets the total number of screening outcomes (match + no-match + unresolved) recorded against the sanctions list. Not a confirmed-matches-only count — see the class summary.' format: int32 peps: type: integer description: 'Gets the total number of screening outcomes (match + no-match + unresolved) recorded against the PEPs list. Not a confirmed-matches-only count — see the class summary.' format: int32 adverseMedia: type: integer description: 'Gets the total number of screening outcomes (match + no-match + unresolved) recorded against adverse media sources. Not a confirmed-matches-only count — see the class summary.' format: int32 additionalProperties: false description: 'Screening detection totals for the platform telemetry section. Sanctions/Peps/AdverseMedia are each the total number of screening outcomes (match + no-match + unresolved) recorded against that list type — NOT a confirmed-matches-only count. Whether Sanctions + Peps + AdverseMedia sums to Total is not established: it depends on whether Fenergo.Nebula.Screening emits the category-suffixed measures as a strict partition of Total''s underlying measures or as a separate/overlapping per-list-type flow (e.g. a single hit checked against multiple lists could be counted in more than one category). Do not assume either way without checking Fenergo.Nebula.Screening''s emission code first. Sanctions/Peps/AdverseMedia read 0 for all tenants until Fenergo.Nebula.Screening''s category-metrics feature flag is enabled — AB#543743/AB#543745 have both shipped to master, but the underlying capability rollout is a separate, tenant-by-tenant flag flip.' ServiceResponseMessage: type: object properties: message: type: - string - 'null' type: type: - string - 'null' errorCode: type: - string - 'null' additionalProperties: false CapacityMeasureCreditDto: type: object properties: measureKey: type: - string - 'null' description: The metered event type this entry covers (e.g. `IDP_field_extracted_count`). isMetered: type: boolean description: '`false` when this measure has no rate resolvable and no historical frozen consumption either (Guardrail §6 — "not metered", never "0%").' creditsConsumed: type: - number - 'null' description: Total credits consumed for this measure (closed-period frozen sum + open-period live calculation). `null`, never `0`, when Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.CapacityMeasureCreditDto.IsMetered is `false`. format: double rateEffectiveFrom: type: - string - 'null' description: The effective-from date of whichever rate version most recently priced this measure. `null` if never metered. format: date additionalProperties: false description: 'One metered sub-event''s credit contribution within a Fenergo.Nebula.BusinessMetrics.Query.Application.Queries.Features.GetAgentValueStory.CapacityAgentCreditsDto (AB#550218 D1). Mirrors Fenergo.Nebula.BusinessMetrics.Domain.Models.Assumptions.CapacityMeasureConsumptionResult 1:1 — this is the granularity Kyra:Docs'' classification/extraction sub-counts are surfaced at underneath the single combined "Docs" display line (Guardrail §7).' securitySchemes: Bearer: type: apiKey description: Please insert JWT with Bearer into field name: Authorization in: header