import {z} from 'zod' export type LinkRequest = string; export type Token = string; export type SaveData = boolean; export type CreateApiApiRiskInsightsArgs = {omit?: string | undefined, fields?: string | undefined, body: {link: LinkRequest, token?: Token | undefined, save_data?: SaveData | undefined}}; export type CreateApiApiRiskInsightsOptions = {baseUrl?: string | undefined, basicAuth?: {username: string, password: string} | undefined, fetch?: typeof fetch | undefined}; export const id = z.string(); export const link = z.string().nullable(); export const createdAt = z.string(); export const riskInsightsAssetMetrics = z.object({institutions: z.array(z.string()).nullable(), num_assets_accounts: z.number().int().nullable().optional(), num_checking_accounts: z.number().int().nullable(), num_savings_accounts: z.number().int().nullable(), checking_accounts_balance: z.number().nullable(), savings_accounts_balance: z.number().nullable()}).nullable(); export const riskInsightsCreditCardMetrics = z.object({num_accounts: z.number().int().gte(0), sum_credit_limit: z.number().nullable(), sum_credit_used: z.number().nullable(), credit_card_limit_utilization: z.number().nullable()}).nullable(); export const riskInsightsLoansMetrics = z.object({num_accounts: z.number().int(), sum_loans_principal: z.number().nullable(), sum_loans_outstanding_principal: z.number().nullable(), sum_loans_monthly_payment: z.number().nullable(), loan_limit_utilization: z.number().nullable(), overdraft_limit: z.number().nullable(), overdraft_limit_utilization: z.number().nullable()}).nullable(); export const riskInsightsBalanceMetrics = z.object({closing_balance: z.number().nullable(), min_balance_3d: z.number().nullable(), min_balance_1w: z.number().nullable(), min_balance_1m: z.number().nullable(), min_balance_3m: z.number().nullable(), min_balance_6m: z.number().nullable(), min_balance_12m: z.number().nullable(), mean_balance_3d: z.number().nullable(), mean_balance_1w: z.number().nullable(), mean_balance_1m: z.number().nullable(), mean_balance_3m: z.number().nullable(), mean_balance_6m: z.number().nullable(), mean_balance_12m: z.number().nullable(), max_balance_3d: z.number().nullable(), max_balance_1w: z.number().nullable(), max_balance_1m: z.number().nullable(), max_balance_3m: z.number().nullable(), max_balance_6m: z.number().nullable(), max_balance_12m: z.number().nullable(), std_balance_3d: z.number().nullable(), std_balance_1w: z.number().nullable(), std_balance_1m: z.number().nullable(), std_balance_3m: z.number().nullable(), std_balance_6m: z.number().nullable(), std_balance_12m: z.number().nullable(), balance_trend_3d: z.number().nullable(), balance_trend_1w: z.number().nullable(), balance_trend_1m: z.number().nullable(), balance_trend_3m: z.number().nullable(), balance_trend_6m: z.number().nullable(), balance_trend_12m: z.number().nullable(), days_balance_below_0_3d: z.number().int().nullable(), days_balance_below_0_1w: z.number().int().nullable(), days_balance_below_0_1m: z.number().int().nullable(), days_balance_below_0_3m: z.number().int().nullable(), days_balance_below_0_6m: z.number().int().nullable(), days_balance_below_0_12m: z.number().int().nullable(), days_balance_below_mean_3d: z.number().int().nullable(), days_balance_below_mean_1w: z.number().int().nullable(), days_balance_below_mean_1m: z.number().int().nullable(), days_balance_below_mean_3m: z.number().int().nullable(), days_balance_below_mean_6m: z.number().int().nullable(), days_balance_below_mean_12m: z.number().int().nullable(), days_balance_below_x_3d: z.number().int().nullable(), days_balance_below_x_1w: z.number().int().nullable(), days_balance_below_x_1m: z.number().int().nullable(), days_balance_below_x_3m: z.number().int().nullable(), days_balance_below_x_6m: z.number().int().nullable(), days_balance_below_x_12m: z.number().int().nullable(), balance_threshold_x: z.number()}).nullable(); export const riskInsightsTransactionMetrics = z.object({num_transactions_3d: z.number().int(), num_transactions_1w: z.number().int(), num_transactions_1m: z.number().int(), num_transactions_3m: z.number().int(), num_transactions_6m: z.number().int(), num_transactions_12m: z.number().int(), max_num_transactions_3d: z.number().int(), max_num_transactions_1w: z.number().int(), max_num_transactions_1m: z.number().int(), max_num_transactions_3m: z.number().int(), max_num_transactions_6m: z.number().int(), max_num_transactions_12m: z.number().int(), mean_num_transactions_3d: z.number(), mean_num_transactions_1w: z.number(), mean_num_transactions_1m: z.number(), mean_num_transactions_3m: z.number(), mean_num_transactions_6m: z.number(), mean_num_transactions_12m: z.number(), num_incoming_transactions_3d: z.number().int(), num_incoming_transactions_1w: z.number().int(), num_incoming_transactions_1m: z.number().int(), num_incoming_transactions_3m: z.number().int(), num_incoming_transactions_6m: z.number().int(), num_incoming_transactions_12m: z.number().int(), max_num_incoming_transactions_3d: z.number().int(), max_num_incoming_transactions_1w: z.number().int(), max_num_incoming_transactions_1m: z.number().int(), max_num_incoming_transactions_3m: z.number().int(), max_num_incoming_transactions_6m: z.number().int(), max_num_incoming_transactions_12m: z.number().int(), mean_num_incoming_transactions_3d: z.number(), mean_num_incoming_transactions_1w: z.number(), mean_num_incoming_transactions_1m: z.number(), mean_num_incoming_transactions_3m: z.number(), mean_num_incoming_transactions_6m: z.number(), mean_num_incoming_transactions_12m: z.number(), sum_incoming_amount_3d: z.number().nullable(), sum_incoming_amount_1w: z.number().nullable(), sum_incoming_amount_1m: z.number().nullable(), sum_incoming_amount_3m: z.number().nullable(), sum_incoming_amount_6m: z.number().nullable(), sum_incoming_amount_12m: z.number().nullable(), max_incoming_amount_3d: z.number().nullable(), max_incoming_amount_1w: z.number().nullable(), max_incoming_amount_1m: z.number().nullable(), max_incoming_amount_3m: z.number().nullable(), max_incoming_amount_6m: z.number().nullable(), max_incoming_amount_12m: z.number().nullable(), mean_incoming_amount_3d: z.number().nullable(), mean_incoming_amount_1w: z.number().nullable(), mean_incoming_amount_1m: z.number().nullable(), mean_incoming_amount_3m: z.number().nullable(), mean_incoming_amount_6m: z.number().nullable(), mean_incoming_amount_12m: z.number().nullable(), num_outgoing_transactions_3d: z.number().int(), num_outgoing_transactions_1w: z.number().int(), num_outgoing_transactions_1m: z.number().int(), num_outgoing_transactions_3m: z.number().int(), num_outgoing_transactions_6m: z.number().int(), num_outgoing_transactions_12m: z.number().int(), max_num_outgoing_transactions_3d: z.number().int(), max_num_outgoing_transactions_1w: z.number().int(), max_num_outgoing_transactions_1m: z.number().int(), max_num_outgoing_transactions_3m: z.number().int(), max_num_outgoing_transactions_6m: z.number().int(), max_num_outgoing_transactions_12m: z.number().int(), mean_num_outgoing_transactions_3d: z.number(), mean_num_outgoing_transactions_1w: z.number(), mean_num_outgoing_transactions_1m: z.number(), mean_num_outgoing_transactions_3m: z.number(), mean_num_outgoing_transactions_6m: z.number(), mean_num_outgoing_transactions_12m: z.number(), sum_outgoing_amount_3d: z.number().nullable(), sum_outgoing_amount_1w: z.number().nullable(), sum_outgoing_amount_1m: z.number().nullable(), sum_outgoing_amount_3m: z.number().nullable(), sum_outgoing_amount_6m: z.number().nullable(), sum_outgoing_amount_12m: z.number().nullable(), max_outgoing_amount_3d: z.number().nullable(), max_outgoing_amount_1w: z.number().nullable(), max_outgoing_amount_1m: z.number().nullable(), max_outgoing_amount_3m: z.number().nullable(), max_outgoing_amount_6m: z.number().nullable(), max_outgoing_amount_12m: z.number().nullable(), mean_outgoing_amount_3d: z.number().nullable(), mean_outgoing_amount_1w: z.number().nullable(), mean_outgoing_amount_1m: z.number().nullable(), mean_outgoing_amount_3m: z.number().nullable(), mean_outgoing_amount_6m: z.number().nullable(), mean_outgoing_amount_12m: z.number().nullable(), days_without_transactions_3d: z.number().int(), days_without_transactions_1w: z.number().int(), days_without_transactions_1m: z.number().int(), days_without_transactions_3m: z.number().int(), days_without_transactions_6m: z.number().int(), days_without_transactions_12m: z.number().int(), days_since_last_transaction: z.number().int(), days_since_last_incoming_transaction: z.number().int(), days_since_last_outgoing_transaction: z.number().int(), days_history: z.number().int()}).nullable(); export const riskInsightsCashflowMetrics = z.object({max_positive_3d: z.number().nullable(), max_positive_1w: z.number().nullable(), max_positive_1m: z.number().nullable(), max_positive_3m: z.number().nullable(), max_positive_6m: z.number().nullable(), max_positive_12m: z.number().nullable(), max_negative_3d: z.number().nullable(), max_negative_1w: z.number().nullable(), max_negative_1m: z.number().nullable(), max_negative_3m: z.number().nullable(), max_negative_6m: z.number().nullable(), max_negative_12m: z.number().nullable(), mean_positive_3d: z.number().nullable(), mean_positive_1w: z.number().nullable(), mean_positive_1m: z.number().nullable(), mean_positive_3m: z.number().nullable(), mean_positive_6m: z.number().nullable(), mean_positive_12m: z.number().nullable(), mean_negative_3d: z.number().nullable(), mean_negative_1w: z.number().nullable(), mean_negative_1m: z.number().nullable(), mean_negative_3m: z.number().nullable(), mean_negative_6m: z.number().nullable(), mean_negative_12m: z.number().nullable(), sum_positive_3d: z.number().nullable(), sum_positive_1w: z.number().nullable(), sum_positive_1m: z.number().nullable(), sum_positive_3m: z.number().nullable(), sum_positive_6m: z.number().nullable(), sum_positive_12m: z.number().nullable(), sum_positive_trend_3d: z.number().nullable(), sum_positive_trend_1w: z.number().nullable(), sum_positive_trend_1m: z.number().nullable(), sum_positive_trend_3m: z.number().nullable(), sum_positive_trend_6m: z.number().nullable(), sum_positive_trend_12m: z.number().nullable(), sum_negative_3d: z.number().nullable(), sum_negative_1w: z.number().nullable(), sum_negative_1m: z.number().nullable(), sum_negative_3m: z.number().nullable(), sum_negative_6m: z.number().nullable(), sum_negative_12m: z.number().nullable(), sum_negative_trend_3d: z.number().nullable(), sum_negative_trend_1w: z.number().nullable(), sum_negative_trend_1m: z.number().nullable(), sum_negative_trend_3m: z.number().nullable(), sum_negative_trend_6m: z.number().nullable(), sum_negative_trend_12m: z.number().nullable(), positive_to_negative_ratio_3d: z.number().nullable(), positive_to_negative_ratio_1w: z.number().nullable(), positive_to_negative_ratio_1m: z.number().nullable(), positive_to_negative_ratio_3m: z.number().nullable(), positive_to_negative_ratio_6m: z.number().nullable(), positive_to_negative_ratio_12m: z.number().nullable(), net_cashflow_3d: z.number().nullable(), net_cashflow_1w: z.number().nullable(), net_cashflow_1m: z.number().nullable(), net_cashflow_3m: z.number().nullable(), net_cashflow_6m: z.number().nullable(), net_cashflow_12m: z.number().nullable(), net_cashflow_trend_3d: z.number().nullable(), net_cashflow_trend_1w: z.number().nullable(), net_cashflow_trend_1m: z.number().nullable(), net_cashflow_trend_3m: z.number().nullable(), net_cashflow_trend_6m: z.number().nullable(), net_cashflow_trend_12m: z.number().nullable()}).nullable(); export const enumTransactionCategory = z.enum(["Bills & Utilities", "Credits & Loans", "Deposits", "Fees & Charges", "Food & Groceries", "Home & Life", "Income & Payments", "Insurance", "Investments & Savings", "Online Platforms & Leisure", "Personal Shopping", "Taxes", "Transfers", "Transport & Travel", "Unknown", "Withdrawal & ATM", "null"]).nullable(); export const enumTransactionSubcategory = z.enum(["Electricity & Energy", "Rent", "Telecommunications", "Water", "Auto", "Credit Card", "Instalment", "Interest & Charges", "Mortgage", "Pay Advance", "Personal", "Adjustments", "Bank Fees", "Chargeback", "Refund", "Blocked Balances", "Alimony", "Alcohol & Tobacco", "Bakery & Coffee", "Bars & Nightclubs", "Convenience Store", "Delivery", "Groceries", "Restaurants", "Education", "Gyms & Fitness", "Hair & Beauty", "Health", "Home Decor & Appliances", "Laundry & Dry Cleaning", "Pharmacies", "Professional Services", "Veterinary Services", "Freelance", "Interest", "Retirement", "Salary", "Government", "Home Insurance", "Auto Insurance", "Health & Life Insurance", "Savings", "Fixed income", "Equity", "Investment Funds", "Derivatives", "Cryptocurrencies", "Apps, Software and Cloud Services", "Events, Parks and Museums", "Gambling", "Gaming", "Lottery", "Movie & Audio", "Books & News", "Clothing & Accessories", "Department Store", "Electronics", "E-commerce", "Gifts", "Office Supplies", "Pet Supplies", "Auto Tax & Fees", "Donation", "Government Fees", "Income Tax", "Real Estate Tax & Fees", "Tax Return", "Accommodation", "Auto Expenses", "Auto Rental", "Flights", "Gas", "Mileage Programs", "Parking & Tolls", "Public Transit", "Taxis & Rideshares", "Other", "null"]).nullable(); export const riskInsightsCategoryMetrics = z.object({category: enumTransactionCategory.optional(), subcategory: enumTransactionSubcategory.optional(), net_amount_3m: z.number().nullable().optional(), category_inflow_ratio_3m: z.number().nullable().optional(), trend_3m: z.number().nullable().optional()}); export const riskInsights = z.object({id: id, link: link, created_at: createdAt, accounts: z.array(z.string()).nullable(), assets_metrics: riskInsightsAssetMetrics, credit_cards_metrics: riskInsightsCreditCardMetrics, loans_metrics: riskInsightsLoansMetrics, balances_metrics: riskInsightsBalanceMetrics, transactions_metrics: riskInsightsTransactionMetrics, cashflow_metrics: riskInsightsCashflowMetrics, category_metrics: z.array(riskInsightsCategoryMetrics)}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Retrieve risk insights for a link * * POST /api/risk-insights/ */ export const createApiApiRiskInsights = async (args: CreateApiApiRiskInsightsArgs, options?: CreateApiApiRiskInsightsOptions) => { const {baseUrl = "https://sandbox.belvo.com", fetch: fetchFn = fetch, basicAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (args.omit != null) query.append("omit", String(args.omit)) if (args.fields != null) query.append("fields", String(args.fields)) if (basicAuth !== undefined) headers.set('authorization', `Basic ${btoa(`${basicAuth.username}:${basicAuth.password}`)}`) const url = `${baseUrl.replace(/\/+$/, '')}/api/risk-insights/${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(riskInsights, await res.json()) };