openapi: 3.1.0 info: title: Trusted AI Analyst Data API version: '1.0.0' description: > Data endpoints powering the analyst dashboard, portfolio-wide transaction review, company search, and per-company transaction drill-down experiences. servers: - url: http://trusted_ai.test/api description: Local development (composer run dev) - url: https://afc.trai.sft.comstack.de/api description: Production tags: - name: Dashboard description: KPIs and alert overviews for the landing dashboard. - name: Transactions description: Portfolio-wide transaction review tooling. - name: Companies description: Company discovery and drill-down data. components: securitySchemes: sessionCookie: type: apiKey in: cookie name: laravel_session description: Browser session issued after login; required for all endpoints documented here. schemas: PaginationMeta: type: object required: - page - perPage - total - lastPage properties: page: type: integer minimum: 1 example: 1 perPage: type: integer minimum: 1 example: 12 total: type: integer minimum: 0 example: 128 lastPage: type: integer minimum: 1 example: 11 CountAmountSummary: type: object required: - count - amount properties: count: type: integer minimum: 0 example: 42 amount: type: number format: double example: 2750000.5 description: Monetary volume in EUR unless noted otherwise. StatusOption: type: object required: - value - label properties: value: type: string example: true_positive label: type: string example: Bestätigte Treffer ChannelOption: type: object required: - value - label properties: value: type: string example: SEPA label: type: string example: SEPA RiskSegment: type: object required: - label - count - volume properties: label: type: string example: Kritisch (≥80) count: type: integer example: 17 volume: type: number format: double example: 8900000.0 TopCompanyAlert: type: object required: - companyId - companyName - ticker - sector - alerts - alertVolume - avgRiskScore properties: companyId: type: integer example: 24 companyName: type: string example: Allianz SE ticker: type: string example: ALV sector: type: string example: Insurance alerts: type: integer example: 6 alertVolume: type: number format: double example: 1450000.0 avgRiskScore: type: integer minimum: 0 maximum: 100 example: 82 DashboardOverview: type: object required: - generatedAt - activeAnalysts - totalTransactions - totalVolume - alertsToday - averageAlertsPerAnalyst - precisionRate - activeAlerts - riskSegments - topCompanies - runbooksExecutedToday properties: generatedAt: type: string format: date-time example: '2025-01-19T07:30:00Z' activeAnalysts: type: integer example: 24 totalTransactions: type: integer example: 312 totalVolume: type: number format: double example: 98765432.1 alertsToday: type: integer example: 56 averageAlertsPerAnalyst: type: integer example: 3 precisionRate: type: integer minimum: 0 maximum: 100 example: 84 activeAlerts: type: object required: - count - highRiskCount properties: count: type: integer example: 128 highRiskCount: type: integer example: 19 riskSegments: type: array items: $ref: '#/components/schemas/RiskSegment' topCompanies: type: array maxItems: 3 items: $ref: '#/components/schemas/TopCompanyAlert' runbooksExecutedToday: type: integer example: 41 TransactionStatus: type: string enum: - true_positive - false_positive - cleared CompanySummary: type: object required: - id - name - legalName - ticker - sector - country - headquarters - kycRiskLevel - summary properties: id: type: integer example: 12 name: type: string example: Allianz legalName: type: string example: Allianz SE ticker: type: string example: ALV sector: type: string example: Insurance country: type: string example: Germany headquarters: type: string example: Munich kycRiskLevel: type: string example: high summary: type: string example: Multinational insurance provider with EMEA focus. CompanyDetail: allOf: - $ref: '#/components/schemas/CompanySummary' - type: object properties: createdAt: type: string format: date-time nullable: true updatedAt: type: string format: date-time nullable: true TransactionPreview: type: object required: - id - company - counterparty - counterpartyCountry - status - statusLabel - requiresReview - riskScore - amount - currency - reference - channel - executedAt properties: id: type: integer example: 512 company: $ref: '#/components/schemas/CompanySummary' counterparty: type: string example: Alpine Holdings Ltd. counterpartyCountry: type: string example: Switzerland status: $ref: '#/components/schemas/TransactionStatus' statusLabel: type: string example: Bestätigter Treffer requiresReview: type: boolean example: true riskScore: type: integer minimum: 0 maximum: 100 example: 87 amount: type: number format: double example: 245000.75 currency: type: string example: EUR reference: type: string example: PAY-2024-10-1942 channel: type: string example: SWIFT executedAt: type: string format: date-time example: '2025-01-18T09:14:00Z' flaggedReason: type: string nullable: true example: Counterparty on sanctions watchlist TransactionSignal: type: object required: - type - value properties: type: type: string example: Adverse Media value: type: string example: Enforcement action reported in 2024-11 weight: type: number format: double nullable: true example: 0.8 AlertSummary: type: object required: - id - counterparty - executedAt - channel - status - statusLabel properties: id: type: integer example: 911 counterparty: type: string example: Northbridge Trading Ltd. executedAt: type: string format: date-time example: '2025-01-18T14:52:00Z' channel: type: string example: SWIFT status: $ref: '#/components/schemas/TransactionStatus' statusLabel: type: string example: Bestätigter Treffer riskScore: type: integer minimum: 0 maximum: 100 example: 92 TransactionHistoryItem: type: object required: - id - executedAt - channel - reference - amount - currency - riskScore properties: id: type: integer example: 877 executedAt: type: string format: date-time example: '2024-12-22T15:37:00Z' channel: type: string example: SWIFT reference: type: string example: PAY-2024-12-1187 amount: type: number format: double example: 99000.0 currency: type: string example: EUR riskScore: type: integer minimum: 0 maximum: 100 example: 74 RecommendedAction: type: object required: - title - description properties: title: type: string example: Verdachtsmeldung vorbereiten description: type: string example: Erstellen Sie den Meldeentwurf für die FIU und sichern Sie Belege. TransactionDetail: allOf: - $ref: '#/components/schemas/TransactionPreview' - type: object required: - flaggedBy - flaggedReason - signals properties: flaggedBy: type: string example: Screening Engine flaggedReason: type: string example: Counterparty matched to EU sanctions list signals: type: array items: $ref: '#/components/schemas/TransactionSignal' TransactionCaseFile: allOf: - $ref: '#/components/schemas/TransactionDetail' - type: object properties: recommendedActions: type: array items: $ref: '#/components/schemas/RecommendedAction' counterpartyHistory: type: array items: $ref: '#/components/schemas/TransactionHistoryItem' TransactionMetrics: type: object required: - total - byStatus properties: total: $ref: '#/components/schemas/CountAmountSummary' byStatus: type: object additionalProperties: $ref: '#/components/schemas/CountAmountSummary' description: Breakdown keyed by transaction status. CompanyTransactionMetrics: type: object required: - totalCount - totalVolume - openAlerts - highRiskShare - last30Days - byStatus properties: totalCount: type: integer example: 96 totalVolume: type: number format: double example: 7200000.0 openAlerts: $ref: '#/components/schemas/CountAmountSummary' highRiskShare: type: integer minimum: 0 maximum: 100 example: 28 last30Days: $ref: '#/components/schemas/CountAmountSummary' byStatus: type: object additionalProperties: $ref: '#/components/schemas/CountAmountSummary' TransactionCollectionResponse: type: object required: - filters - metrics - data - pagination properties: filters: type: object properties: statusOptions: type: array items: $ref: '#/components/schemas/StatusOption' perPage: type: integer example: 12 metrics: $ref: '#/components/schemas/TransactionMetrics' data: type: array items: $ref: '#/components/schemas/TransactionPreview' pagination: $ref: '#/components/schemas/PaginationMeta' selectedTransactionId: type: integer nullable: true example: 512 selectedTransaction: allOf: - $ref: '#/components/schemas/TransactionDetail' nullable: true CompanySearchOverview: type: object required: - totalCompanies - openAlerts - openAlertVolume - averageRiskScore - watchlistHits - automationShare properties: totalCompanies: type: integer example: 40 openAlerts: type: integer example: 112 openAlertVolume: type: number format: double example: 5640000.0 averageRiskScore: type: integer minimum: 0 maximum: 100 example: 71 watchlistHits: type: integer example: 9 automationShare: type: integer minimum: 0 maximum: 100 example: 82 CompanyAlertPreview: type: object required: - transactionId - counterparty - executedAt - channel - flaggedReason properties: transactionId: type: integer example: 731 counterparty: type: string example: Baltic Commodities LLC executedAt: type: string format: date-time example: '2025-01-17T11:48:00Z' channel: type: string example: SWIFT flaggedReason: type: string example: Pattern matches sanctions typology riskScore: type: integer minimum: 0 maximum: 100 example: 88 CompanySearchResult: allOf: - $ref: '#/components/schemas/CompanySummary' - type: object required: - alertCount - alertVolume - alertRiskScore - latestAlert properties: alertCount: type: integer example: 7 alertVolume: type: number format: double example: 980000.0 alertRiskScore: type: integer minimum: 0 maximum: 100 example: 79 latestAlert: allOf: - $ref: '#/components/schemas/CompanyAlertPreview' CompanySearchResponse: type: object required: - overview - results - meta properties: overview: $ref: '#/components/schemas/CompanySearchOverview' results: type: array items: $ref: '#/components/schemas/CompanySearchResult' meta: type: object required: - query - resultCount - limit properties: query: type: string nullable: true example: Allianz resultCount: type: integer example: 6 limit: type: integer example: 6 CompanyTransactionsResponse: type: object required: - company - filters - metrics - data - pagination properties: company: $ref: '#/components/schemas/CompanyDetail' filters: type: object properties: statusOptions: type: array items: $ref: '#/components/schemas/StatusOption' channelOptions: type: array items: $ref: '#/components/schemas/ChannelOption' metrics: $ref: '#/components/schemas/CompanyTransactionMetrics' data: type: array items: $ref: '#/components/schemas/TransactionPreview' pagination: $ref: '#/components/schemas/PaginationMeta' selectedTransactionId: type: integer nullable: true example: 877 selectedTransaction: allOf: - $ref: '#/components/schemas/TransactionCaseFile' nullable: true recentAlerts: type: array items: $ref: '#/components/schemas/AlertSummary' paths: /dashboard/overview: get: tags: - Dashboard operationId: getDashboardOverview summary: Retrieve dashboard overview metrics description: > Aggregated KPIs and alert slices needed for the dashboard hero cards and side panels. security: - sessionCookie: [] responses: '200': description: Overview data ready for dashboard rendering. content: application/json: schema: $ref: '#/components/schemas/DashboardOverview' '401': description: Session invalid or expired. /transactions: get: tags: - Transactions operationId: listTransactions summary: List transactions with global filters description: > Returns the paginated transaction stream together with per-status metrics and default selection, mirroring the Livewire transaction review experience. security: - sessionCookie: [] parameters: - name: search in: query schema: type: string description: Match against reference, counterparty, or company identifiers. - name: status in: query schema: type: string enum: - all - true_positive - false_positive - cleared default: all description: Filter by review status; `all` keeps every status. - name: page in: query schema: type: integer minimum: 1 default: 1 - name: perPage in: query schema: type: integer minimum: 1 maximum: 100 default: 12 responses: '200': description: Paginated transaction set with metrics. content: application/json: schema: $ref: '#/components/schemas/TransactionCollectionResponse' '401': description: Session invalid or expired. /transactions/{transactionId}: get: tags: - Transactions operationId: getTransactionCaseFile summary: Fetch a single transaction case file description: > Detailed transaction record used when an analyst expands a case in the transaction review workspace. security: - sessionCookie: [] parameters: - name: transactionId in: path required: true schema: type: integer responses: '200': description: Transaction detail with detection signals. content: application/json: schema: $ref: '#/components/schemas/TransactionDetail' '401': description: Session invalid or expired. '404': description: Transaction not found. /companies/search: get: tags: - Companies operationId: searchCompanies summary: Search companies and retrieve screening overview description: > Provides the metrics and top results required to populate the company search tiles. security: - sessionCookie: [] parameters: - name: q in: query schema: type: string description: Free-text query across name, legal name, ticker, or sector. - name: limit in: query schema: type: integer minimum: 1 maximum: 25 default: 6 responses: '200': description: Matching companies with alert context. content: application/json: schema: $ref: '#/components/schemas/CompanySearchResponse' '401': description: Session invalid or expired. /companies/{companyId}: get: tags: - Companies operationId: getCompany summary: Retrieve a company profile description: > Returns core firmographics and KYC risk tier needed for per-company transaction pages. security: - sessionCookie: [] parameters: - name: companyId in: path required: true schema: type: integer responses: '200': description: Company detail. content: application/json: schema: $ref: '#/components/schemas/CompanyDetail' '401': description: Session invalid or expired. '404': description: Company not found. /companies/{companyId}/transactions: get: tags: - Companies operationId: listCompanyTransactions summary: List transactions for a specific company description: > Supplies per-company metrics, channel/status filters, paginated cases, and the current selection for the company drill-down view. security: - sessionCookie: [] parameters: - name: companyId in: path required: true schema: type: integer - name: status in: query schema: type: string enum: - all - true_positive - false_positive - cleared default: all - name: channel in: query schema: type: string default: all description: Channel label returned in channelOptions; use `all` for no filtering. - name: page in: query schema: type: integer minimum: 1 default: 1 - name: perPage in: query schema: type: integer minimum: 1 maximum: 100 default: 10 responses: '200': description: Company-specific transaction data with metrics. content: application/json: schema: $ref: '#/components/schemas/CompanyTransactionsResponse' '401': description: Session invalid or expired. '404': description: Company not found or no transactions. /companies/{companyId}/transactions/{transactionId}: get: tags: - Companies operationId: getCompanyTransactionCaseFile summary: Fetch a company transaction case file with history description: > Returns the selected transaction enriched with recommended actions and counterparty history used in the right-hand panel of the company drill-down. security: - sessionCookie: [] parameters: - name: companyId in: path required: true schema: type: integer - name: transactionId in: path required: true schema: type: integer responses: '200': description: Transaction case file for the company context. content: application/json: schema: $ref: '#/components/schemas/TransactionCaseFile' '401': description: Session invalid or expired. '404': description: Transaction not found for the given company.