LimitRail Developer Console
Public API workbench for OAuth clients
API https://stg-api.limitrail.com OAuth https://stg-oauth.limitrail.com Token missing Docs IT Docs EN Swagger
Integration playbook

LimitRail guida di configurazione e integrazione

Documentazione operativa per configurare il sistema e integrare le API pubbliche.

LimitRail - guida di configurazione e integrazione

Questa guida spiega come configurare LimitRail e come integrarlo da un sistema esterno. È pensata per due lettori:

  • chi configura prodotti, operazioni, fee e limiti nel backoffice;
  • chi integra le API pubbliche da un core, da una piattaforma di integrazione o da un canale digitale.

LimitRail non autorizza direttamente il movimento di denaro e non possiede il saldo del conto. LimitRail decide la policy: calcola fee, verifica limiti, riserva capacità e produce evidenza leggibile. Il sistema chiamante resta responsabile dell'esecuzione dell'operazione finanziaria.

Vai subito alla guida operativa: Appendice A - Playbook operativo di configurazione e integrazione.

1. Che cosa fa LimitRail

LimitRail è un motore di policy, pricing e limiti. Il sistema chiamante invia:

  • account esterno;
  • codice operazione;
  • importo e valuta, se richiesti;
  • metadata runtime, se la policy dipende da informazioni dell'operazione;
  • modalità di valutazione: solo preview, riserva capacità o commit immediato.

LimitRail restituisce:

  • decisione di policy: ALLOWED, DENIED_BY_POLICY, WARNING, FEE_CALCULATED;
  • fee calcolate;
  • limiti e contatori impattati;
  • policy risolta e provenienza;
  • dimensioni usate, mancanti o non usate;
  • eventuale reservation id da confermare o cancellare.
%%{init: {"theme": "base", "themeVariables": {"background": "#ffffff", "mainBkg": "#ffffff", "primaryColor": "#f8fafc", "primaryTextColor": "#0f172a", "primaryBorderColor": "#475569", "lineColor": "#1d4ed8", "textColor": "#0f172a"}}}%%
flowchart LR
    BO[Backoffice LimitRail] --> CFG[Product, operations, dimensions, condition plan]
    CFG --> PUB[Published policy version]
    INT[Core / sistema integratore] --> API[LimitRail public API]
    PUB --> API
    API --> OUT[Decisione, fee, contatori, spiegazione]
    OUT --> INT

2. Configurazione backoffice

2.1 Product

Il product rappresenta il tipo di prodotto commerciale, ad esempio un conto standard, business o premium.

Campo Esempio Perché è importante
code STD_ACCOUNT È il codice stabile usato nelle integrazioni e nelle policy.
name Account Standard È il nome leggibile per operatori e demo.
currencyCode EUR È la valuta base usata quando la richiesta runtime non specifica una valuta.
status ACTIVE Solo prodotti attivi devono essere usati in runtime.
defaultConditionPlanId ... Collega il prodotto al pacchetto di pricing e limiti.

Regola pratica: il product code è un contratto tecnico. Non deve essere rinominato liberamente dopo che un integratore lo usa.

2.2 Operation catalog

Una operation è il codice operativo ricevuto dal sistema chiamante. Se il core invia A14, LimitRail deve conoscere A14. Non serve un mapping aggiuntivo quando il codice ricevuto è già il codice canonico condiviso.

Campo Esempio Effetto runtime
code A14 Codice che arriva in operationCode nella chiamata runtime.
name International wire transfer Testo leggibile per UI, audit e documentazione.
familyCode TRANSFER Raggruppa operazioni simili.
channelCode WIRE_TRANSFER Alimenta la system dimension channel.
requiresAmount true Se manca amount, la chiamata runtime viene rifiutata.
requiresPricingCoverage true La readiness segnala se manca pricing.
requiresLimitCoverage true La readiness segnala se manca un limite.

Esempio:

{
  "code": "A14",
  "name": "International wire transfer",
  "familyCode": "TRANSFER",
  "channelCode": "WIRE_TRANSFER",
  "requiresAmount": true,
  "requiresPricingCoverage": true,
  "requiresLimitCoverage": true
}

2.3 Policy dimensions

Le policy dimensions sono il vocabolario controllato delle informazioni che il motore può usare per decidere. Non sono semplici note libere e non sono campi messi lì per descrivere una transazione. Una dimensione risponde a una domanda precisa: "questo dato può cambiare una fee, un limite, un contatore o una spiegazione audit?"

Esempi di domande di business che diventano dimensions:

  • Il bonifico va verso un paese domestico o estero?
  • Il cliente è retail, business, VIP o dipendente?
  • L'operazione arriva da mobile, filiale, API o batch?
  • Il pagamento è istantaneo?
  • Il cliente è residente o non residente?
  • Questa informazione deve separare i limiti oppure serve solo per scegliere quale regola applicare?
Campo Significato
code Nome tecnico della dimensione. Viene normalizzato in minuscolo nel runtime context.
displayName Nome leggibile.
dataType STRING, DECIMAL, INTEGER, BOOLEAN, DATE, ENUM.
source Da dove arriva il valore: REQUEST_METADATA, ACCOUNT_ATTRIBUTE, SYSTEM.
allowedValues Lista opzionale di valori ammessi. Serve quando il dato deve essere controllato, per esempio solo ITA, FRA, DEU, ESP, USA come paesi supportati. Se arriva XXX, LimitRail rifiuta la richiesta invece di applicare una regola sbagliata.
isRuleEnabled Indica se questa informazione può essere usata per far scattare o non far scattare una regola di pricing o limite. Esempio: se wire_country_destination = FRA, applica fee internazionale; se customer_tier = GOLD, applica fee ridotta.
canUseInCounterScopes Indica se questa informazione può entrare nella chiave del limite, cioè nel modo in cui LimitRail accumula i consumi. Esempio: un limite giornaliero può essere unico per tutti i bonifici, oppure può avere un contenitore diverso per ogni paese destinazione. Se abiliti questa opzione per wire_country_destination, il consumo verso FRA può essere contato in un contenitore diverso dal consumo verso USA.
isSensitive Indica se il valore deve essere nascosto nelle risposte e nei log leggibili. Esempio: una dimensione di rischio può influenzare la policy, ma non deve apparire in usedDimensions se è sensibile.

2.3.1 Come leggere questi campi senza tecnicismi

allowedValues: controllare che l'integratore mandi valori corretti

Usalo quando vuoi impedire valori non previsti. Per esempio, se la dimensione wire_country_destination accetta solo ITA, FRA, DEU, ESP, USA, allora una richiesta con wire_country_destination = "BR" viene rifiutata se BR non è configurato. Questo evita che una transazione venga trattata come "caso generico" quando invece il prodotto non ha regole per quel valore.

Esempio pratico:

{
  "metadata": {
    "wire_country_destination": "FRA"
  }
}

Se FRA è tra i valori ammessi, la valutazione continua. Se arriva UNKNOWN_COUNTRY, il runtime risponde con errore funzionale.

isRuleEnabled: usare il dato per scegliere quale regola applicare

Questa opzione significa: "le regole possono leggere questa informazione". Una regola di pricing o limite può avere una condizione del tipo:

  • applica questa fee solo se wire_country_destination è diverso da ITA;
  • applica questo limite solo se customer_tier è BASIC;
  • non applicare questa fee se employee = true;
  • blocca l'operazione se risk_segment = HIGH e l'importo supera una soglia.

In altre parole, isRuleEnabled decide se la dimensione può entrare nella logica decisionale. Non abilitarlo per campi che vuoi solo conservare o mostrare, ma che non devono cambiare la decisione.

Esempio di logica:

Dato ricevuto Regola configurata Risultato
wire_country_destination = ITA fee internazionale solo se paese diverso da ITA fee internazionale non applicata
wire_country_destination = FRA fee internazionale solo se paese diverso da ITA fee internazionale applicata
customer_tier = GOLD fee ridotta per clienti GOLD fee ridotta applicata
employee = true fee azzerata per dipendenti fee azzerata

canUseInCounterScopes: usare il dato per separare il consumo dei limiti

Questa opzione non decide se la regola vale. Decide come viene contato il consumo.

Esempio 1: limite unico per operazione.

  • Regola: massimo 10.000 EUR al giorno per bonifici A14.
  • Scope: account + operation.
  • Risultato: tutti i bonifici A14 dello stesso account consumano lo stesso limite giornaliero.

Esempio 2: limite separato per paese destinazione.

  • Regola: massimo 10.000 EUR al giorno per bonifici A14, separato per wire_country_destination.
  • Scope: account + operation + wire_country_destination.
  • Risultato: 6.000 EUR verso FRA e 6.000 EUR verso USA finiscono in due contatori diversi.

Questa scelta è potente ma va usata con attenzione. Non usare mai valori troppo variabili, come transaction id, descrizione libera o riferimento operazione, per separare i contatori: genererebbero troppi contatori e peggiorerebbero costo e performance.

isSensitive: usare il dato senza mostrarlo

Una dimensione sensibile può influenzare la policy ma non deve essere mostrata nella risposta leggibile. Esempio: risk_segment = HIGH può bloccare o irrigidire un limite, ma potresti non volerlo esporre al chiamante o in schermate operative non autorizzate.

2.4 Tre tipi di dimensioni

System dimensions

Sono calcolate dal runtime, non vanno inviate nei metadata:

Dimensione Valore
operation operation code risolto, per esempio A14.
channel channel code dell'operazione, per esempio WIRE_TRANSFER.
segment segment code dell'account, se presente.
product product code dell'account.
currency valuta richiesta o valuta account.

Request metadata

Sono valori che cambiano per singola operazione. Si inviano dentro metadata nella chiamata runtime o nel commit.

Esempi:

  • wire_country_destination = "ITA": destinazione del bonifico;
  • beneficiary_bank_country = "DEU": paese banca beneficiaria;
  • channel_risk_score = 72: score calcolato dal canale;
  • is_instant = true: flag bonifico istantaneo.

Usali quando la decisione dipende dalla transazione specifica.

Account attributes

Sono valori stabili dell'account. Si salvano sull'account contract o tramite API account attributes.

Esempi:

  • customer_tier = "GOLD";
  • residency = "IT";
  • risk_segment = "LOW";
  • employee = true.

Usali quando la decisione dipende dal profilo dell'account, non dalla singola transazione.

2.5 Esempio: perché i metadata contano

Scenario: i bonifici internazionali verso paesi non domestici costano di più e hanno un limite giornaliero separato per paese destinazione.

Configurazione:

  • dimensione wire_country_destination, source REQUEST_METADATA, type ENUM;
  • allowed values: ITA, FRA, DEU, ESP, USA;
  • pricing rule: se wire_country_destination != "ITA", applica fee internazionale. In parole semplici: il paese destinazione decide quale fee usare;
  • limit rule: perimetro del contatore custom con wire_country_destination. In parole semplici: il paese destinazione decide anche dove accumulare il consumo del limite.

Runtime request payload:

{
  "externalAccountRef": "000100000203",
  "operationCode": "A14",
  "amount": 2500.00,
  "currencyCode": "EUR",
  "externalOperationRef": "wire-2026-000001",
  "occurredAtUtc": "2026-06-13T10:15:00Z",
  "metadata": {
    "wire_country_destination": "FRA"
  },
  "mode": "PREVIEW"
}

Effetto nel motore:

  • operation, channel, product, currency vengono aggiunte automaticamente;
  • wire_country_destination viene validata contro il registry;
  • le condizioni delle regole che leggono wire_country_destination possono attivare o escludere pricing e limiti;
  • se la dimensione è parte del perimetro del contatore, il contatore non sarà solo account + operation, ma anche wire_country_destination;
  • la risposta indicherà la dimensione in usedDimensions se non è sensibile.

2.6 Scenari di limiti e fee su un conto di pagamento

Questa sezione usa esempi generici per mostrare come trasformare requisiti di prodotto in configurazione LimitRail. Lo scopo non è copiare un catalogo operativo specifico, ma far capire quali dati devono diventare operation, quali devono diventare dimensioni e quali regole sono applicabili dal motore.

2.6.1 Che cosa è applicabile oggi e che cosa richiede dati esterni

Requisito di prodotto Applicabilità in LimitRail Come configurarlo
Fee fissa per una operazione, per esempio 0,35 EUR su un servizio specifico Applicabile oggi Pricing rule FIXED sull'operation code.
Operazione gratuita Applicabile oggi Pricing rule WAIVER, oppure nessuna pricing rule se non vuoi mostrare una fee a zero. Usa WAIVER quando vuoi rendere esplicito che quella operazione è inclusa.
Limite mensile di volume, per esempio 2.400 EUR al mese per account Applicabile oggi Limit rule AMOUNT, MONTHLY, blocking, con counter scope ACCOUNT_GLOBAL, ACCOUNT_CHANNEL o ACCOUNT_OPERATION in base al perimetro desiderato.
Limite annuale sul numero di operazioni incluse, poi fee Applicabile oggi quando la quota è per singolo operation code Pricing rule TIERED, metrica COUNT, periodo YEARLY, tiers con primo scaglione a fee zero e scaglione successivo a fee piena.
Quota annuale condivisa fra più operation code diversi Applicabile se modellata con un unico operation code canonico Oggi il tiered pricing accumula per account + operation. Se la quota deve essere unica su più varianti, usa un unico operation code e una dimensione per distinguere il dettaglio. Se mantieni codici separati, la quota resta separata per codice.
Fee basata sull'importo della singola operazione, per esempio gratuita fino a 35 EUR e poi 0,30 EUR Applicabile se il sistema chiamante invia una fascia importo come metadata Oggi le condizioni leggono dimensioni governate, non direttamente l'amount come campo di condizione. Configura una dimensione amount_band e fai calcolare al chiamante UP_TO_35 o ABOVE_35.
Fee mensile basata su saldo medio Applicabile solo se il saldo medio arriva da fuori LimitRail non calcola saldi medi. Il sistema contabile calcola average_monthly_balance e lo invia come metadata della fee mensile o lo salva come account attribute.
Saldo massimo conto, per esempio 3.600 EUR Applicabile solo se il sistema chiamante fornisce il saldo proiettato LimitRail non possiede il saldo. Il chiamante deve inviare projected_balance_after_operation; LimitRail può bloccare quando quel valore supera la soglia.
Eccezione temporanea su una singola operazione Applicabile come dato esplicito, non come processo operativo completo Il chiamante può inviare limit_exception_granted = true o usare un account override temporaneo. Il processo di approvazione resta nel sistema operativo che governa ruoli e autorizzazioni.

2.6.2 Product e operation catalog consigliati

Esempio di product:

{
  "code": "RETAIL_EUR_ACCOUNT",
  "name": "Retail EUR Account",
  "currencyCode": "EUR",
  "status": "ACTIVE"
}

Esempio di operation catalog neutrale:

Operation code Nome funzionale Direction Channel Amount required Perché serve
ACCOUNT_OPENING Apertura conto NEUTRAL ACCOUNT_SERVICE No Serve se vuoi rendere esplicita una fee di apertura, anche quando è zero.
MONTHLY_MAINTENANCE Canone mensile conto DEBIT ACCOUNT_SERVICE No Operazione schedulata dal sistema chiamante per calcolare eventuale canone.
INCOMING_STANDARD_TRANSFER Bonifico entrante standard CREDIT TRANSFER Yes Può consumare capacità di funding o controllare il saldo massimo.
INCOMING_INSTANT_TRANSFER Bonifico entrante istantaneo CREDIT TRANSFER Yes Stesso dominio del bonifico entrante, ma distinguibile per pricing o audit.
OUTGOING_STANDARD_TRANSFER Bonifico uscente standard DEBIT TRANSFER Yes Può consumare limiti mensili e quota annuale inclusa.
OUTGOING_INSTANT_TRANSFER Bonifico uscente istantaneo DEBIT TRANSFER Yes Può avere fee o quota diversa da quello standard.
INTERNATIONAL_TRANSFER Trasferimento area estera DEBIT TRANSFER Yes Esempio classico di fee fissa o limite più restrittivo.
DIRECT_DEBIT_COLLECTION Addebito diretto DEBIT DIRECT_DEBIT Yes Può essere gratuito ma comunque consumare limiti globali.
DIRECT_DEBIT_REVOCATION Revoca addebito diretto DEBIT DIRECT_DEBIT No Può avere fee fissa.
DIRECT_DEBIT_CHARGEBACK Contestazione addebito diretto DEBIT DIRECT_DEBIT No Può avere fee fissa superiore.
P2P_PAYMENT Pagamento persona a persona DEBIT DIGITAL_PAYMENT Yes Può avere fee solo sopra una soglia importo.
MERCHANT_PAYMENT Pagamento esercente DEBIT DIGITAL_PAYMENT Yes Tipicamente gratuito lato cliente.
PUBLIC_SERVICE_PAYMENT Pagamento servizio pubblico DEBIT DIGITAL_PAYMENT Yes Può avere fee fissa.
TRANSFER_REVERSAL Storno o rimborso trasferimento DEBIT EXCEPTION No Fee operativa per gestione eccezioni.

2.6.3 Dimensioni da configurare e perché

Queste dimensioni coprono scenari reali di limiti e fee senza mettere logica nascosta nei sistemi integratori.

Dimensione Source Tipo Valori Configurazione consigliata Uso pratico
transfer_speed REQUEST_METADATA ENUM STANDARD, INSTANT isRuleEnabled = true, canUseInCounterScopes = false Serve quando un unico codice operazione rappresenta più varianti e vuoi applicare fee diverse a standard e istantaneo. Non serve come counter scope se il limite è unico per tutti i trasferimenti.
destination_area REQUEST_METADATA ENUM DOMESTIC, REGIONAL, INTERNATIONAL isRuleEnabled = true, canUseInCounterScopes = true solo se vuoi limiti separati per area Serve per applicare una fee diversa ai trasferimenti esteri o per separare i limiti per area destinazione.
amount_band REQUEST_METADATA ENUM UP_TO_35, ABOVE_35 isRuleEnabled = true, canUseInCounterScopes = false Serve per regole tipo "gratis fino a 35 EUR, poi 0,30 EUR". Il chiamante calcola la fascia dall'importo e LimitRail la usa per scegliere la fee.
projected_balance_after_operation REQUEST_METADATA DECIMAL Nessuna lista isRuleEnabled = true, canUseInCounterScopes = false, isStoredInRuntimeLog = true se vuoi audit Serve per bloccare operazioni entranti che porterebbero il conto oltre il saldo massimo. Il valore deve arrivare dal sistema che possiede il saldo.
average_monthly_balance REQUEST_METADATA o ACCOUNT_ATTRIBUTE DECIMAL Nessuna lista isRuleEnabled = true, canUseInCounterScopes = false Serve per decidere se applicare il canone mensile. Se cambia ogni mese, invialo come metadata della chiamata MONTHLY_MAINTENANCE.
customer_profile ACCOUNT_ATTRIBUTE ENUM STANDARD, PREMIUM, STAFF, RESTRICTED isRuleEnabled = true, canUseInCounterScopes = false Serve per condizioni commerciali o operative legate al profilo del conto. Esempio: staff senza canone, profilo restricted con limiti più bassi.
limit_exception_granted REQUEST_METADATA BOOLEAN true/false isRuleEnabled = true, canUseInCounterScopes = false, isSensitive = true se non vuoi mostrarla Serve quando un sistema operativo ha approvato una deroga su una singola operazione. LimitRail legge il flag e applica una regola alternativa.

Nota importante: canUseInCounterScopes va acceso solo quando vuoi davvero separare i contatori. Per destination_area può avere senso: 1.000 EUR verso area domestica e 1.000 EUR verso area internazionale possono consumare contenitori diversi. Per amount_band no: separare i contatori per fascia importo renderebbe più difficile leggere il limite e raramente corrisponde al comportamento commerciale.

2.6.4 Esempio: volume transazioni 2.400 EUR al mese

Obiettivo: ogni account può movimentare al massimo 2.400 EUR al mese sulle operazioni monitorate.

Configurazione:

  • crea una limit rule LIM_MONTHLY_VOLUME_2400;
  • MetricType = AMOUNT;
  • PeriodType = MONTHLY;
  • LimitAmount = 2400.00;
  • IsBlocking = true;
  • CounterScopeMode = ACCOUNT_GLOBAL se il limite è unico per account;
  • OperationScope = GLOBAL se devono contribuire tutte le operazioni valutate dalla policy;
  • WindowTimeZone = Europe/Rome se il mese deve seguire il calendario italiano.

Effetto: se l'account ha già consumato 2.180 EUR nel mese e arriva un'operazione da 300 EUR, il motore calcola 2.480 EUR proiettati e restituisce DENIED_BY_POLICY con il codice regola LIM_MONTHLY_VOLUME_2400.

2.6.5 Esempio: 9 trasferimenti inclusi all'anno, poi 0,35 EUR

Obiettivo: i primi 9 trasferimenti annui sono inclusi; dal decimo in poi il cliente paga 0,35 EUR per operazione.

Configurazione nativa se la quota è per operation code:

  • pricing rule FEE_OUT_TRANSFER_YEARLY_TIER;
  • CalculationMethod = TIERED;
  • MetricType = COUNT;
  • PeriodType = YEARLY;
  • OperationScope = OPERATION_CODE;
  • OperationCode = OUTGOING_STANDARD_TRANSFER;
  • tiers:
[
  { "upTo": 9, "amount": 0.00 },
  { "upTo": null, "amount": 0.35 }
]

Come leggerla: fino a quando il contatore annuo dell'account per OUTGOING_STANDARD_TRANSFER è sotto 9, la fee calcolata è zero. Dal trasferimento successivo, la fee diventa 0,35 EUR.

Attenzione: oggi il tiered pricing accumula su account + operation. Se vuoi una quota unica condivisa fra OUTGOING_STANDARD_TRANSFER e OUTGOING_INSTANT_TRANSFER, hai due strade:

  • modellare un unico operation code OUTGOING_TRANSFER e distinguere standard/istantaneo con la dimensione transfer_speed;
  • oppure accettare due quote separate, una per operation code.

2.6.6 Esempio: pagamento persona a persona gratuito fino a 35 EUR

Obiettivo: il pagamento persona a persona è gratuito fino a 35 EUR; sopra 35 EUR costa 0,30 EUR.

Poiché oggi le condizioni leggono dimensioni governate, configura una dimensione:

{
  "code": "amount_band",
  "displayName": "Amount band",
  "dataType": "ENUM",
  "source": "REQUEST_METADATA",
  "allowedValues": ["UP_TO_35", "ABOVE_35"],
  "isRuleEnabled": true
}

Il sistema chiamante invia:

{
  "externalAccountRef": "acc_000203",
  "operationCode": "P2P_PAYMENT",
  "amount": 48.00,
  "currencyCode": "EUR",
  "metadata": {
    "amount_band": "ABOVE_35"
  },
  "mode": "PREVIEW"
}

Pricing:

  • regola WAIVER con condizione amount_band = UP_TO_35;
  • regola FIXED 0.30 EUR con condizione amount_band = ABOVE_35.

Questo è esplicito e auditabile: LimitRail non deve indovinare la fascia, ma può spiegare quale fascia ha ricevuto e quale fee ha applicato.

2.6.7 Esempio: canone mensile basato su saldo medio

Obiettivo: canone gratuito se il saldo medio mensile è almeno 220 EUR; altrimenti 0,70 EUR.

LimitRail non calcola il saldo medio. Il sistema che possiede i saldi deve calcolarlo e chiamare LimitRail con una operation schedulata:

{
  "externalAccountRef": "acc_000203",
  "operationCode": "MONTHLY_MAINTENANCE",
  "amount": 0,
  "currencyCode": "EUR",
  "metadata": {
    "average_monthly_balance": 186.40
  },
  "mode": "PREVIEW"
}

Configurazione:

  • dimensione average_monthly_balance, tipo DECIMAL, source REQUEST_METADATA;
  • pricing rule FIXED 0.70 EUR;
  • condizione: average_monthly_balance < 220.

Se il valore è 186,40, la fee si applica. Se il valore è 220 o superiore, la regola non scatta e non viene addebitato canone.

2.6.8 Esempio: saldo massimo conto

Obiettivo: impedire che un accredito porti il saldo del conto sopra 3.600 EUR.

LimitRail non ha il saldo contabile. Il chiamante deve inviare il saldo proiettato dopo l'operazione:

{
  "externalAccountRef": "acc_000203",
  "operationCode": "INCOMING_STANDARD_TRANSFER",
  "amount": 280.00,
  "currencyCode": "EUR",
  "metadata": {
    "projected_balance_after_operation": 3650.00
  },
  "mode": "PREVIEW"
}

Configurazione possibile:

  • dimensione projected_balance_after_operation, tipo DECIMAL, source REQUEST_METADATA;
  • limit rule LIM_MAX_BALANCE_3600;
  • MetricType = AMOUNT;
  • PeriodType = SINGLE;
  • LimitAmount = 0;
  • IsBlocking = true;
  • condizione: projected_balance_after_operation > 3600.

Come leggerla: la regola non sta usando i contatori storici; sta usando il valore calcolato dal sistema saldo. Quando il saldo proiettato supera 3.600 EUR, qualsiasi accredito positivo viene negato dalla policy. Se vuoi gestire tolleranze o deroghe, aggiungi la dimensione limit_exception_granted e una regola alternativa più permissiva.

2.6.9 Esempio: eccezione temporanea

Obiettivo: consentire una singola operazione anche se supera una policy standard, perché un operatore autorizzato ha concesso una deroga.

Configurazione:

  • dimensione limit_exception_granted, tipo BOOLEAN, source REQUEST_METADATA;
  • isRuleEnabled = true;
  • isSensitive = true se non vuoi esporre il valore nella risposta leggibile;
  • regola standard blocking senza deroga;
  • regola alternativa o assenza di blocco quando limit_exception_granted = true.

Runtime request payload:

{
  "externalAccountRef": "acc_000203",
  "operationCode": "INCOMING_STANDARD_TRANSFER",
  "amount": 280.00,
  "currencyCode": "EUR",
  "metadata": {
    "projected_balance_after_operation": 3650.00,
    "limit_exception_granted": true
  },
  "mode": "RESERVE_CAPACITY",
  "idempotencyKey": "reserve-acc_000203-20260613-001"
}

LimitRail può registrare che la decisione è stata valutata con una deroga, ma non sostituisce il workflow autorizzativo. Chi approva la deroga, con quali ruoli e per quanto tempo, resta responsabilità del sistema di gestione operativa a monte.

3. Condition plan e versioni

Il condition plan è il pacchetto di regole di pricing e limite. Una versione può essere:

  • DRAFT: modificabile;
  • PUBLISHED: usata dal runtime e non modificabile;
  • ARCHIVED: storica.

Le API runtime pubbliche non accettano override della versione. La chiamata runtime pubblica risolve sempre la versione pubblicata corretta per account, segmento o prodotto. Per confronti con una draft si usa la superficie admin di simulazione, non /v1/policy/evaluate.

3.1 Ordine di risoluzione policy

Quando arriva una richiesta runtime, LimitRail risolve la policy in questo ordine:

  1. override specifico account;
  2. policy specifica del segmento;
  3. policy di default del prodotto.

Questo significa:

  • l'override account è un'eccezione per un singolo account, per esempio un limite negoziato o una condizione commerciale temporanea;
  • la policy di segmento si usa solo quando un gruppo di account dello stesso prodotto deve seguire regole pubblicate diverse, per esempio studenti, premium, dipendenti, non residenti o account in migrazione;
  • la policy di default del prodotto è la configurazione normale e viene usata quando non esistono override account o policy specifiche per il segmento.

Il segmento è opzionale. Non creare segmenti solo perché il campo esiste. Usalo solo quando il business sa spiegare perché quel gruppo deve avere fee, limiti o vincoli operativi diversi dal default del prodotto.

Se non trova una condition plan version pubblicata, la decisione non può applicare regole e il reason code indica assenza di policy.

4. Account onboarding

4.1 Account contract

Un account contract collega un account esterno a un prodotto LimitRail.

Payload consigliato:

{
  "externalAccountRef": "000100000203",
  "productId": "865e0567-7927-4680-a2f5-e4c71921b7bf",
  "segmentCode": "PRIVATE",
  "openedAtUtc": "2026-06-13T09:00:00Z",
  "attributes": {
    "customer_tier": "GOLD",
    "residency": "IT"
  }
}

Note:

  • externalAccountRef deve essere opaco e stabile;
  • non usare IBAN, nome, email, codice fiscale o dati personali;
  • attributes viene validato contro le dimensions con source ACCOUNT_ATTRIBUTE;
  • l'inserimento account e attributi deve essere atomico.

4.2 Segment

Il segmento è opzionale. È un gruppo business usato dalla risoluzione policy, non un campo obbligatorio di classificazione cliente.

Usalo quando lo stesso prodotto ha più di una policy pubblicata perché un gruppo di account richiede regole diverse. Esempi tipici:

  • PRIVATE;
  • BUSINESS;
  • VIP;
  • NON_RESIDENT;
  • EMPLOYEE.

Per esempio, se PAYMENT_ACCOUNT ha una policy standard e una policy dipendenti, gli account con segmentCode = EMPLOYEE possono risolvere la condition plan version dei dipendenti. Gli account senza segmento, o con un segmento senza assegnazione, ricadono sul default del prodotto.

Se non esistono policy di segmento, lascia segmentCode vuoto. Non bisogna inventare segmenti solo per riempire il campo.

4.3 Account override

Un override account assegna una policy pubblicata a un account specifico. È utile per:

  • accordi corporate;
  • condizioni negoziate;
  • eccezioni commerciali temporanee;
  • clienti con limiti speciali.

Se non esiste override, il runtime usa la policy specifica del segmento quando esiste; altrimenti usa la policy di default del prodotto.

5. OAuth client e scope

L'integrazione pubblica usa OAuth2/OIDC con client_credentials.

Token request:

POST /connect/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
client_id=lr_...
client_secret=...
scope=limitrail.catalog.read limitrail.accounts.read limitrail.accounts.write limitrail.evaluate limitrail.usage.write

Scope:

Scope Uso
limitrail.catalog.read discovery di prodotti, operazioni e dimensions.
limitrail.accounts.read lettura account, pricing risolto e contatori.
limitrail.accounts.write registrazione account e attributi.
limitrail.evaluate preview, reserve o commit diretto della policy runtime.
limitrail.usage.write commit, cancel reservation, reverse usage.
limitrail.audit.read lettura audit runtime quando logging è abilitato.

Il token scade. Il client deve rinnovarlo prima della scadenza e non salvarlo come segreto permanente.

6. Flusso tecnico consigliato

Flusso tecnico consigliato

>Core: access_token
Core->>API: GET /v1/products
Core->>API: GET /v1/operations
Core->>API: POST /v1/account-contracts
Core->>API: POST /v1/policy/evaluate
Core->>API: POST /v1/usage/commit
-->

### Step 1 - Catalog discovery

L'integratore legge il catalogo per verificare codici e dimensioni:

```http
GET /v1/products?take=25
GET /v1/operations?take=25
GET /v1/policy-dimensions

Uso pratico:

  • verificare che STD_ACCOUNT esista;
  • verificare che A14 sia attiva;
  • leggere quali metadata sono ammessi e da dove devono arrivare;
  • costruire UI o validazioni lato integratore senza hardcodare tutto.

Step 2 - Account onboarding

Per ogni account esistente o nuovo:

POST /v1/account-contracts
Authorization: Bearer <token>
Content-Type: application/json

Se gli account sono milioni, il caricamento va fatto a batch. La UI deve cercare per prefisso e caricare a pagina/cursore, non contare tutto.

Step 3 - Runtime preview prima dell'esecuzione

Preview non scrive contatori e non crea reservation. Serve per mostrare fee, verificare policy o fare una pre-verifica.

POST /v1/policy/evaluate
Authorization: Bearer <token>
Content-Type: application/json

{
  "externalAccountRef": "000100000203",
  "operationCode": "A14",
  "amount": 2500.00,
  "currencyCode": "EUR",
  "externalOperationRef": "wire-2026-000001",
  "metadata": {
    "wire_country_destination": "FRA"
  },
  "mode": "PREVIEW"
}

Risposta tipica:

{
  "decision": "FEE_CALCULATED",
  "reasonCode": "FEE_A14_1",
  "originalAmount": 2500.00,
  "totalFees": 0.40,
  "currencyCode": "EUR",
  "conditionPlanCode": "STD_ACCOUNT_PLAN",
  "conditionPlanVersionNumber": 1,
  "fees": [
    {
      "ruleCode": "FEE_A14_1",
      "amount": 0.40,
      "currencyCode": "EUR"
    }
  ],
  "usedDimensions": {
    "operation": "A14",
    "channel": "WIRE_TRANSFER",
    "product": "STD_ACCOUNT",
    "currency": "EUR",
    "wire_country_destination": "FRA"
  },
  "missingDimensions": [],
  "unusedDimensions": []
}

Step 4 - Reserve capacity

Reserve crea una prenotazione temporanea dei limiti. Serve quando l'operazione può fallire dopo la verifica.

{
  "externalAccountRef": "000100000203",
  "operationCode": "A14",
  "amount": 2500.00,
  "currencyCode": "EUR",
  "externalOperationRef": "wire-2026-000001",
  "metadata": {
    "wire_country_destination": "FRA"
  },
  "mode": "RESERVE_CAPACITY",
  "idempotencyKey": "reserve-wire-2026-000001"
}

Se la decisione è consentita, la risposta contiene:

  • capacityReservationId;
  • capacityReservationExpiresAtUtc;
  • fee e limit impacts calcolati.

Step 5 - Commit usage

Commit conferma l'uso dei contatori. Può avvenire in due modi:

  1. commit di una reservation già creata;
  2. commit diretto tramite POST /v1/policy/evaluate con mode = COMMIT_USAGE.

Commit di reservation:

{
  "capacityReservationId": "2e337d1a-0b51-4fd5-a90a-4dcc7a47fd50",
  "idempotencyKey": "commit-wire-2026-000001",
  "externalAccountRef": "000100000203",
  "operationCode": "A14",
  "amount": 2500.00,
  "currencyCode": "EUR",
  "externalOperationRef": "wire-2026-000001",
  "metadata": {
    "wire_country_destination": "FRA"
  }
}

La reservation deve combaciare con account, operation, amount, currency ed external operation reference. Se non combacia, il runtime rifiuta il commit.

Step 6 - Cancel reservation

Cancel si usa quando una reservation non deve diventare usage committed:

{
  "capacityReservationId": "2e337d1a-0b51-4fd5-a90a-4dcc7a47fd50",
  "reason": "Operation expired before execution"
}

Step 7 - Reverse usage

Reverse storna un usage già committed. Non è la stessa cosa di cancel:

  • cancel = reservation non confermata;
  • reverse = usage già applicato da compensare.
{
  "reversalIdempotencyKey": "reverse-wire-2026-000001",
  "reason": "Transfer cancelled after settlement rejection",
  "reversedAtUtc": "2026-06-13T11:20:00Z"
}

7. Come leggere una decisione denied

Una decisione DENIED_BY_POLICY significa che LimitRail ha trovato una regola limite blocking che verrebbe superata. Il campo reasonCode contiene il codice della regola che ha bloccato.

Campi utili:

Campo Come leggerlo
decision Esito di policy. Non è autorizzazione finanziaria finale.
reasonCode ALLOWED, NO_CONDITION_PLAN oppure codice regola che ha prodotto l'esito.
ruleResults Dettaglio delle regole valutate.
limitImpacts Quali scope contatore sarebbero impattati.
usedDimensions Dimensioni effettivamente entrate nel contesto e non sensibili.
missingDimensions Dimensioni referenziate da regole o scope ma non presenti nel contesto.
unusedDimensions Metadata inviati ma non referenziati da regole o scope.

Esempio: se reasonCode = "LIM_A14_1" e ruleResults mostra projected amount oltre soglia, il racconto corretto è: "la policy ha negato perché il limite configurato dalla regola LIM_A14_1 sarebbe stato superato".

8. Counter scope: perché conta

Il counter scope è il perimetro del contatore: decide "dove finisce" il consumo di una operazione. È uno dei concetti più importanti del prodotto, perché lo stesso limite può essere interpretato in modi molto diversi.

Esempio semplice:

  • un cliente fa tre bonifici A14 da 1.000 EUR;
  • LimitRail deve decidere se quei 3.000 EUR consumano un unico limite globale, un limite solo dei bonifici, un limite del canale wire transfer o un limite separato per paese destinazione.

Questa scelta non è tecnica: è business. Decide come il prodotto controlla il comportamento del cliente.

Mode Aggregazione
ACCOUNT_OPERATION account + operation. Esempio: totale A14 giornaliero dell'account.
ACCOUNT_CHANNEL account + channel. Esempio: totale canale WIRE_TRANSFER.
ACCOUNT_GLOBAL solo account. Esempio: limite giornaliero globale.
CUSTOM_DIMENSIONS account + dimensions configurate. Esempio: account + operation + paese destinazione.

8.1 Esempi di business

Limite globale giornaliero account

Obiettivo: il cliente non può consumare più di 20.000 EUR al giorno su tutte le operazioni monitorate.

Configurazione:

  • mode: ACCOUNT_GLOBAL;
  • periodo: DAILY;
  • metrica: AMOUNT;
  • soglia: 20.000 EUR.

Risultato: bonifici, pagamenti e altre operazioni consumano lo stesso contenitore giornaliero dell'account.

Limite per tipo operazione

Obiettivo: il cliente può fare massimo 10.000 EUR al giorno di bonifici internazionali A14.

Configurazione:

  • mode: ACCOUNT_OPERATION;
  • operation: A14;
  • periodo: DAILY;
  • soglia: 10.000 EUR.

Risultato: solo le operazioni A14 consumano quel contatore. Altre operazioni hanno contatori separati.

Limite per canale

Obiettivo: limitare tutto il canale WIRE_TRANSFER, indipendentemente dal singolo codice operazione.

Configurazione:

  • mode: ACCOUNT_CHANNEL;
  • channel: WIRE_TRANSFER;
  • periodo: DAILY;
  • soglia: 15.000 EUR.

Risultato: più codici operazione dello stesso canale consumano lo stesso limite.

Limite per paese destinazione

Obiettivo: controllare separatamente i bonifici verso paesi diversi.

Configurazione:

  • mode: CUSTOM_DIMENSIONS;
  • dimensione: wire_country_destination;
  • periodo: DAILY;
  • soglia: 10.000 EUR per paese.

Risultato: il consumo verso FRA non si somma al consumo verso USA. Ogni paese ha il suo contatore per quell'account.

Se una dimensione è usata nel perimetro del contatore, deve essere presente nella richiesta o configurata con includeWhenMissing. Attenzione alle dimensioni ad alta cardinalità: usare un valore come transaction id, reference operazione o descrizione libera creerebbe troppi contatori e peggiorerebbe costi e performance.

9. Audit e runtime logging

Audit & Explain mostra solo valutazioni salvate. Se logging mode è NONE, la pagina resta vuota.

Logging mode:

  • NONE: nessuna evaluation loggata;
  • DENIED_ONLY: logga solo denied;
  • SAMPLED: logga un campione;
  • FULL: logga tutto, utile per demo o diagnosi, costoso in produzione.

Le query audit richiedono sempre From e To. Questo evita scansioni su tabelle runtime grandi.

10. Regole pratiche per integratori

  • Usare sempre enum uppercase: ACTIVE, PREVIEW, RESERVE_CAPACITY, COMMIT_USAGE, DAILY, MONTHLY.
  • Non inviare dati personali in externalAccountRef.
  • Inviare solo metadata registrati nel registry.
  • Usare idempotencyKey per tutte le chiamate che scrivono stato.
  • Non riutilizzare la stessa idempotency key per payload diversi.
  • Rinnovare il token prima della scadenza.
  • Gestire 400, 401, 403, 404, 409, 422 come errori funzionali.
  • Usare search per prefisso e cursor/load-more sulle liste grandi.

Appendice A - Playbook operativo di configurazione e integrazione

Questo playbook è una checklist prescrittiva. Parte dai casi più semplici e arriva ai casi più articolati. Ogni scenario dice:

  • dove configurare il caso nel backoffice;
  • quale campo valorizzare;
  • quale effetto produce nel motore;
  • quale chiamata deve fare il sistema chiamante.

A.1 Setup minimo del prodotto

Obiettivo: avere un prodotto attivo con operazioni, policy pubblicata e credenziali OAuth.

Step Dove vai Cosa imposti Valore di esempio Effetto
1 Product Workspace Product code RETAIL_EUR_ACCOUNT Codice stabile che l'integratore leggerà da /v1/products.
2 Product Workspace currencyCode EUR Valuta base del prodotto.
3 Operation Catalog Operation code OUTGOING_TRANSFER Codice che il chiamante userà in operationCode.
4 Operation Catalog direction DEBIT Dice al runtime che l'operazione consuma capacità.
5 Operation Catalog channelCode TRANSFER Permette limiti e fee per intero canale.
6 Operation Catalog requiresAmount true La chiamata runtime viene rifiutata se manca amount.
7 Condition plans Crea condition plan RETAIL_EUR_PLAN Contenitore delle regole di fee e limiti.
8 Policy Studio Pubblica versione PUBLISHED Solo una versione pubblicata è usata dalle API runtime.
9 Product Workspace Collega plan al product defaultConditionPlanId Il runtime risolve la policy dal prodotto se non esistono override.
10 Developer access Crea OAuth client scope necessari Il chiamante può ottenere token e chiamare le API pubbliche.

Chiamate minime del sistema chiamante:

POST /connect/token
GET /v1/products?take=25
GET /v1/operations?take=25
GET /v1/policy-dimensions
POST /v1/account-contracts
POST /v1/policy/evaluate

Token request:

POST /connect/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
client_id=lr_...
client_secret=...
scope=limitrail.catalog.read limitrail.accounts.read limitrail.accounts.write limitrail.evaluate limitrail.usage.write

Token response:

{
  "access_token": "eyJ...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "limitrail.catalog.read limitrail.accounts.read limitrail.accounts.write limitrail.evaluate limitrail.usage.write"
}

Discovery response essenziale:

[
  {
    "id": "865e0567-7927-4680-a2f5-e4c71921b7bf",
    "externalCoreProductRef": null,
    "code": "RETAIL_EUR_ACCOUNT",
    "name": "Retail EUR Account",
    "status": "ACTIVE",
    "currencyCode": "EUR"
  }
]

A.2 Operazione gratuita esplicita

Usala quando vuoi dimostrare che un'operazione è inclusa nel prodotto, non semplicemente "senza regola".

Dove vai Campo Valore
Operation Catalog code MERCHANT_PAYMENT
Operation Catalog direction DEBIT
Operation Catalog requiresAmount true
Policy Studio > Pricing CalculationMethod WAIVER
Policy Studio > Pricing OperationScope OPERATION_CODE
Policy Studio > Pricing OperationCode MERCHANT_PAYMENT

Effetto: la risposta può mostrare fee a zero e rendere chiaro che la gratuità è una scelta di prodotto.

API request - preview fee:

POST /v1/policy/evaluate
Authorization: Bearer <token>
Content-Type: application/json

{
  "externalAccountRef": "acc_000203",
  "operationCode": "MERCHANT_PAYMENT",
  "amount": 42.00,
  "currencyCode": "EUR",
  "mode": "PREVIEW"
}

API response:

{
  "decision": "FEE_CALCULATED",
  "reasonCode": "FEE_MERCHANT_PAYMENT_INCLUDED",
  "originalAmount": 42.00,
  "totalFees": 0.00,
  "currencyCode": "EUR",
  "fees": [
    {
      "code": "FEE_MERCHANT_PAYMENT_INCLUDED",
      "amount": 0.00,
      "currencyCode": "EUR",
      "description": "Merchant payment included"
    }
  ],
  "usedDimensions": {
    "operation": "MERCHANT_PAYMENT",
    "channel": "DIGITAL_PAYMENT",
    "product": "RETAIL_EUR_ACCOUNT",
    "currency": "EUR"
  }
}

A.3 Fee fissa per singola operazione

Usala quando ogni esecuzione dell'operazione costa sempre lo stesso importo.

Dove vai Campo Valore
Operation Catalog code PUBLIC_SERVICE_PAYMENT
Policy Studio > Pricing CalculationMethod FIXED
Policy Studio > Pricing FixedAmount 0.35
Policy Studio > Pricing CurrencyCode EUR
Policy Studio > Pricing AppliesWhen ON_EVALUATE

Effetto: ogni richiesta runtime per PUBLIC_SERVICE_PAYMENT restituisce una fee di 0,35 EUR se la policy è risolta e la regola non ha condizioni che la escludono.

API request - preview fee:

POST /v1/policy/evaluate
Authorization: Bearer <token>
Content-Type: application/json

{
  "externalAccountRef": "acc_000203",
  "operationCode": "PUBLIC_SERVICE_PAYMENT",
  "amount": 88.00,
  "currencyCode": "EUR",
  "mode": "PREVIEW"
}

API response:

{
  "decision": "FEE_CALCULATED",
  "reasonCode": "FEE_PUBLIC_SERVICE_PAYMENT",
  "originalAmount": 88.00,
  "totalFees": 0.35,
  "currencyCode": "EUR",
  "fees": [
    {
      "code": "FEE_PUBLIC_SERVICE_PAYMENT",
      "amount": 0.35,
      "currencyCode": "EUR",
      "description": "Public service payment fee"
    }
  ]
}

A.4 Fee percentuale con minimo e massimo

Usala per commissioni proporzionali all'importo, ma con guardrail commerciale.

Dove vai Campo Valore
Policy Studio > Pricing CalculationMethod PERCENTAGE
Policy Studio > Pricing PercentageRate 0.0025
Policy Studio > Pricing MinAmount 0.20
Policy Studio > Pricing MaxAmount 4.50
Policy Studio > Pricing FeeBase OPERATION_AMOUNT

Effetto: su 800 EUR la fee teorica è 2,00 EUR. Su importi piccoli il minimo evita fee troppo basse; su importi alti il massimo evita fee troppo alte.

A.5 Volume mensile massimo per account

Usalo quando il prodotto ha un massimale mensile di movimentazione.

Dove vai Campo Valore
Policy Studio > Limits Code LIM_MONTHLY_VOLUME_2400
Policy Studio > Limits MetricType AMOUNT
Policy Studio > Limits PeriodType MONTHLY
Policy Studio > Limits LimitAmount 2400.00
Policy Studio > Limits CounterScopeMode ACCOUNT_GLOBAL
Policy Studio > Limits OperationScope GLOBAL
Policy Studio > Limits IsBlocking true

Effetto: tutte le operazioni valutate dalla policy consumano lo stesso contenitore mensile dell'account. Se il nuovo importo porta il totale sopra 2.400 EUR, la decisione diventa DENIED_BY_POLICY.

API request - reserve capacity:

POST /v1/policy/evaluate
Authorization: Bearer <token>
Content-Type: application/json

{
  "externalAccountRef": "acc_000203",
  "operationCode": "OUTGOING_TRANSFER",
  "amount": 300.00,
  "currencyCode": "EUR",
  "externalOperationRef": "op-20260613-0001",
  "mode": "RESERVE_CAPACITY",
  "idempotencyKey": "reserve-op-20260613-0001"
}

API response quando la capacità viene riservata:

{
  "decision": "ALLOWED",
  "reasonCode": "ALLOWED",
  "capacityReservationId": "2e337d1a-0b51-4fd5-a90a-4dcc7a47fd50",
  "capacityReservationExpiresAtUtc": "2026-06-13T10:20:00Z",
  "limitImpacts": [
    {
      "metricType": "AMOUNT",
      "periodType": "MONTHLY",
      "projectedAmount": 300.00
    }
  ]
}

API request - commit dopo esecuzione dell'operazione:

POST /v1/usage/commit
Authorization: Bearer <token>
Content-Type: application/json

{
  "capacityReservationId": "2e337d1a-0b51-4fd5-a90a-4dcc7a47fd50",
  "externalAccountRef": "acc_000203",
  "operationCode": "OUTGOING_TRANSFER",
  "amount": 300.00,
  "currencyCode": "EUR",
  "externalOperationRef": "op-20260613-0001",
  "idempotencyKey": "commit-op-20260613-0001"
}

API response:

{
  "usageEventId": "7c62f3dd-4ef0-48d0-a95c-9b7f8c0f2a10",
  "status": "APPLIED"
}

A.6 Limite per operation code

Usalo quando vuoi limitare solo una famiglia specifica di operazioni, senza impattare le altre.

Dove vai Campo Valore
Policy Studio > Limits OperationScope OPERATION_CODE
Policy Studio > Limits OperationCode OUTGOING_TRANSFER
Policy Studio > Limits MetricType AMOUNT
Policy Studio > Limits PeriodType DAILY
Policy Studio > Limits LimitAmount 900.00
Policy Studio > Limits CounterScopeMode ACCOUNT_OPERATION

Effetto: solo OUTGOING_TRANSFER consuma questo limite giornaliero. Un pagamento esercente può avere un limite diverso o nessun limite specifico.

A.7 Limite per canale

Usalo quando più operation code devono consumare lo stesso limite, per esempio tutte le operazioni del canale trasferimenti.

Dove vai Campo Valore
Operation Catalog channelCode TRANSFER su tutte le operation correlate
Policy Studio > Limits OperationScope OPERATION_CHANNEL
Policy Studio > Limits ChannelCode TRANSFER
Policy Studio > Limits MetricType AMOUNT
Policy Studio > Limits PeriodType DAILY
Policy Studio > Limits LimitAmount 1200.00
Policy Studio > Limits CounterScopeMode ACCOUNT_CHANNEL

Effetto: OUTGOING_TRANSFER e OUTGOING_INSTANT_TRANSFER, se hanno channelCode = TRANSFER, consumano lo stesso contenitore giornaliero.

A.8 Operazioni incluse, poi fee

Usalo per una quota inclusa: prime N operazioni gratuite, poi fee fissa.

Dove vai Campo Valore
Policy Studio > Pricing CalculationMethod TIERED
Policy Studio > Pricing MetricType COUNT
Policy Studio > Pricing PeriodType YEARLY
Policy Studio > Pricing OperationCode OUTGOING_TRANSFER
Policy Studio > Pricing Tiers[0].UpTo 9
Policy Studio > Pricing Tiers[0].Amount 0.00
Policy Studio > Pricing Tiers[1].UpTo vuoto
Policy Studio > Pricing Tiers[1].Amount 0.35

Effetto: finché il contatore annuo dell'account per OUTGOING_TRANSFER è sotto 9, la fee è zero. Dal trasferimento successivo, la fee è 0,35 EUR.

Nota di modellazione: il tiered pricing oggi conta per account + operation. Se vuoi una quota unica per standard e istantaneo, configura un unico operation code OUTGOING_TRANSFER e usa transfer_speed come dimensione.

A.9 Variante standard / istantanea sullo stesso operation code

Usala quando vuoi evitare quote separate ma vuoi comunque distinguere il caso standard dal caso istantaneo.

Dove vai Campo Valore
Dimension Registry code transfer_speed
Dimension Registry dataType ENUM
Dimension Registry source REQUEST_METADATA
Dimension Registry allowedValues STANDARD, INSTANT
Dimension Registry isRuleEnabled true
Dimension Registry canUseInCounterScopes false
Policy Studio > Pricing Condizione regola standard transfer_speed = STANDARD
Policy Studio > Pricing Condizione regola istantanea transfer_speed = INSTANT

Effetto: il contatore tiered resta su OUTGOING_TRANSFER, quindi la quota è condivisa. La fee può cambiare in base a transfer_speed.

API request - preview con variante:

POST /v1/policy/evaluate
Authorization: Bearer <token>
Content-Type: application/json

{
  "externalAccountRef": "acc_000203",
  "operationCode": "OUTGOING_TRANSFER",
  "amount": 120.00,
  "currencyCode": "EUR",
  "metadata": {
    "transfer_speed": "INSTANT"
  },
  "mode": "PREVIEW"
}

API response:

{
  "decision": "FEE_CALCULATED",
  "reasonCode": "FEE_OUTGOING_TRANSFER_INSTANT",
  "totalFees": 0.35,
  "currencyCode": "EUR",
  "usedDimensions": {
    "operation": "OUTGOING_TRANSFER",
    "channel": "TRANSFER",
    "transfer_speed": "INSTANT",
    "product": "RETAIL_EUR_ACCOUNT",
    "currency": "EUR"
  }
}

A.10 Fee diversa per area destinazione

Usala quando una fee dipende da dove va il trasferimento.

Dove vai Campo Valore
Dimension Registry code destination_area
Dimension Registry dataType ENUM
Dimension Registry source REQUEST_METADATA
Dimension Registry allowedValues DOMESTIC, REGIONAL, INTERNATIONAL
Dimension Registry isRuleEnabled true
Dimension Registry canUseInCounterScopes false per sola fee
Policy Studio > Pricing Regola 1 WAIVER se destination_area = DOMESTIC
Policy Studio > Pricing Regola 2 FIXED 0.65 EUR se destination_area = INTERNATIONAL

Effetto: il sistema chiamante dichiara l'area destinazione, LimitRail valida il valore e applica la fee corretta.

A.11 Limite separato per area destinazione

Usalo quando il consumo verso aree diverse non deve finire nello stesso contatore.

Dove vai Campo Valore
Dimension Registry destination_area.canUseInCounterScopes true
Policy Studio > Limits CounterScopeMode CUSTOM_DIMENSIONS
Policy Studio > Limits Scope dimension destination_area
Policy Studio > Limits MetricType AMOUNT
Policy Studio > Limits PeriodType MONTHLY
Policy Studio > Limits LimitAmount 1800.00

Effetto: 800 EUR verso DOMESTIC e 800 EUR verso INTERNATIONAL consumano due contatori diversi. Usa questa opzione solo se il prodotto vuole davvero separare i limiti per area.

A.12 Fee sopra soglia importo

Usala quando l'importo della singola operazione decide quale fee applicare.

Dove vai Campo Valore
Dimension Registry code amount_band
Dimension Registry dataType ENUM
Dimension Registry source REQUEST_METADATA
Dimension Registry allowedValues UP_TO_35, ABOVE_35
Dimension Registry isRuleEnabled true
Policy Studio > Pricing Regola gratuita WAIVER se amount_band = UP_TO_35
Policy Studio > Pricing Regola a pagamento FIXED 0.30 EUR se amount_band = ABOVE_35

Responsabilità del chiamante: calcolare la fascia dall'importo e inviarla nei metadata.

API request - preview sopra soglia:

POST /v1/policy/evaluate
Authorization: Bearer <token>
Content-Type: application/json

{
  "externalAccountRef": "acc_000203",
  "operationCode": "P2P_PAYMENT",
  "amount": 48.00,
  "currencyCode": "EUR",
  "metadata": {
    "amount_band": "ABOVE_35"
  },
  "mode": "PREVIEW"
}

API response:

{
  "decision": "FEE_CALCULATED",
  "reasonCode": "FEE_P2P_ABOVE_35",
  "originalAmount": 48.00,
  "totalFees": 0.30,
  "currencyCode": "EUR",
  "usedDimensions": {
    "amount_band": "ABOVE_35",
    "operation": "P2P_PAYMENT"
  }
}

A.13 Canone mensile basato su saldo medio

Usalo quando una fee ricorrente dipende da un valore calcolato dal sistema contabile.

Dove vai Campo Valore
Operation Catalog code MONTHLY_MAINTENANCE
Dimension Registry code average_monthly_balance
Dimension Registry dataType DECIMAL
Dimension Registry source REQUEST_METADATA
Dimension Registry isRuleEnabled true
Policy Studio > Pricing CalculationMethod FIXED
Policy Studio > Pricing FixedAmount 0.70
Policy Studio > Pricing Condizione average_monthly_balance < 220

Responsabilità del chiamante: calcolare il saldo medio e chiamare LimitRail a fine periodo o nella schedulazione di billing.

API request - canone periodico:

POST /v1/policy/evaluate
Authorization: Bearer <token>
Content-Type: application/json

{
  "externalAccountRef": "acc_000203",
  "operationCode": "MONTHLY_MAINTENANCE",
  "amount": 0,
  "currencyCode": "EUR",
  "metadata": {
    "average_monthly_balance": 186.40
  },
  "mode": "PREVIEW"
}

API response:

{
  "decision": "FEE_CALCULATED",
  "reasonCode": "FEE_MONTHLY_MAINTENANCE_LOW_BALANCE",
  "totalFees": 0.70,
  "currencyCode": "EUR",
  "usedDimensions": {
    "average_monthly_balance": 186.40,
    "operation": "MONTHLY_MAINTENANCE"
  }
}

A.14 Saldo massimo conto

Usalo quando vuoi bloccare accrediti che porterebbero il conto oltre una soglia. LimitRail non calcola il saldo: legge il saldo proiettato fornito dal sistema chiamante.

Dove vai Campo Valore
Dimension Registry code projected_balance_after_operation
Dimension Registry dataType DECIMAL
Dimension Registry source REQUEST_METADATA
Dimension Registry isRuleEnabled true
Policy Studio > Limits Code LIM_MAX_BALANCE_3600
Policy Studio > Limits PeriodType SINGLE
Policy Studio > Limits IsBlocking true
Policy Studio > Limits Condizione projected_balance_after_operation > 3600

API request - controllo saldo proiettato:

POST /v1/policy/evaluate
Authorization: Bearer <token>
Content-Type: application/json

{
  "externalAccountRef": "acc_000203",
  "operationCode": "INCOMING_STANDARD_TRANSFER",
  "amount": 280.00,
  "currencyCode": "EUR",
  "metadata": {
    "projected_balance_after_operation": 3650.00
  },
  "mode": "PREVIEW"
}

API response:

{
  "decision": "DENIED_BY_POLICY",
  "reasonCode": "LIM_MAX_BALANCE_3600",
  "originalAmount": 280.00,
  "totalFees": 0.00,
  "currencyCode": "EUR",
  "ruleResults": [
    {
      "ruleCode": "LIM_MAX_BALANCE_3600",
      "decision": "DENIED_BY_POLICY",
      "metricType": "AMOUNT",
      "periodType": "SINGLE"
    }
  ],
  "usedDimensions": {
    "projected_balance_after_operation": 3650.00,
    "operation": "INCOMING_STANDARD_TRANSFER"
  }
}

Effetto: la policy nega perché il saldo proiettato supera la soglia. L'esecuzione finanziaria resta responsabilità del chiamante.

A.15 Profilo account o segmento cliente

Usalo quando le condizioni dipendono da una caratteristica stabile del conto.

Dove vai Campo Valore
Dimension Registry code customer_profile
Dimension Registry source ACCOUNT_ATTRIBUTE
Dimension Registry dataType ENUM
Dimension Registry allowedValues STANDARD, PREMIUM, STAFF, RESTRICTED
Dimension Registry isRuleEnabled true
Account contracts attributes.customer_profile PREMIUM
Policy Studio Condizione customer_profile = PREMIUM

Effetto: il chiamante non deve rimandare questo valore a ogni richiesta runtime. LimitRail lo legge dagli attributi dell'account.

API request - creazione account contract:

POST /v1/account-contracts
Authorization: Bearer <token>
Content-Type: application/json

{
  "externalAccountRef": "acc_000203",
  "productId": "865e0567-7927-4680-a2f5-e4c71921b7bf",
  "attributes": {
    "customer_profile": "PREMIUM"
  }
}

API response:

{
  "id": "146dbd98-242f-4f5d-9fc0-b5dbb497cbb5",
  "externalAccountRef": "acc_000203",
  "productId": "865e0567-7927-4680-a2f5-e4c71921b7bf",
  "productCode": "RETAIL_EUR_ACCOUNT",
  "status": "ACTIVE"
}

A.16 Deroga operativa su singola operazione

Usala quando un sistema operativo approva una deroga e LimitRail deve tenerne conto nella valutazione.

Dove vai Campo Valore
Dimension Registry code limit_exception_granted
Dimension Registry dataType BOOLEAN
Dimension Registry source REQUEST_METADATA
Dimension Registry isRuleEnabled true
Dimension Registry isSensitive true se non deve apparire in risposta
Policy Studio Regola restrittiva applica quando limit_exception_granted non esiste o è false
Policy Studio Regola alternativa applica quando limit_exception_granted = true

API request - deroga con riserva:

POST /v1/policy/evaluate
Authorization: Bearer <token>
Content-Type: application/json

{
  "externalAccountRef": "acc_000203",
  "operationCode": "INCOMING_STANDARD_TRANSFER",
  "amount": 280.00,
  "currencyCode": "EUR",
  "metadata": {
    "projected_balance_after_operation": 3650.00,
    "limit_exception_granted": true
  },
  "mode": "RESERVE_CAPACITY",
  "idempotencyKey": "reserve-exception-000203-001"
}

API response:

{
  "decision": "ALLOWED",
  "reasonCode": "ALLOWED",
  "capacityReservationId": "4dfef774-f177-4642-8fb4-7c3dfaf09ea0",
  "usedDimensions": {
    "projected_balance_after_operation": 3650.00,
    "operation": "INCOMING_STANDARD_TRANSFER"
  }
}

Effetto: LimitRail valuta con la deroga. Non decide chi può approvarla: quello resta nel sistema operativo a monte.

A.17 Flusso runtime corretto: preview, reserve, commit

Usalo quando l'operazione può essere verificata, poi eseguita dopo una fase esterna.

Step API Quando usarla Cosa scrive
1 POST /v1/policy/evaluate con mode = PREVIEW Mostrare fee o controllare policy senza impegnare capacità Nulla
2 POST /v1/policy/evaluate con mode = RESERVE_CAPACITY Bloccare temporaneamente capacità mentre il chiamante esegue l'operazione Reservation temporanea
3 POST /v1/usage/commit Confermare che l'operazione è stata eseguita Usage committed e contatori
4 POST /v1/capacity-reservations/{id}/cancel Annullare una reservation non eseguita Cancella reservation
5 POST /v1/usage/{id}/reverse Compensare un usage già committed Usage reversal

Regola pratica: usa sempre idempotencyKey per reserve, commit e reverse. Non riutilizzare la stessa chiave per payload diversi.

A.18 Cosa deve leggere il chiamante per mostrare limiti e fee all'utente finale

Bisogno del canale API Uso
Mostrare il pricing risolto del conto GET /v1/accounts/{externalAccountRef}/pricing Elenco fee applicabili al prodotto/account.
Mostrare i contatori committed del conto GET /v1/accounts/{externalAccountRef}/usage-counters Stato dei limiti consumati, senza dati operativi grezzi.
Simulare una operazione prima dell'esecuzione POST /v1/policy/evaluate con PREVIEW Mostra fee e potenziale denied prima che l'utente confermi.
Impegnare capacità durante l'esecuzione POST /v1/policy/evaluate con RESERVE_CAPACITY Evita race condition tra verifica ed esecuzione.

API request - pricing risolto:

GET /v1/accounts/acc_000203/pricing
Authorization: Bearer <token>

API response:

{
  "externalAccountRef": "acc_000203",
  "productCode": "RETAIL_EUR_ACCOUNT",
  "conditionPlanCode": "RETAIL_EUR_PLAN",
  "versionNumber": 1,
  "currencyCode": "EUR",
  "pricing": [
    {
      "operationCode": "MERCHANT_PAYMENT",
      "method": "WAIVER",
      "summary": "Included in the account package"
    },
    {
      "operationCode": "PUBLIC_SERVICE_PAYMENT",
      "method": "FIXED",
      "amount": 0.35,
      "currencyCode": "EUR"
    }
  ]
}

Uso reale: questa è la chiamata che un canale utente può usare per mostrare "quanto costa" una certa operazione prima di far partire un pagamento. Non consuma contatori.

API request - contatori committed:

GET /v1/accounts/acc_000203/usage-counters
Authorization: Bearer <token>

API response:

{
  "externalAccountRef": "acc_000203",
  "counters": [
    {
      "operationCode": "OUTGOING_TRANSFER",
      "metricType": "AMOUNT",
      "periodType": "MONTHLY",
      "committedAmount": 620.00,
      "limitAmount": 2400.00,
      "remainingAmount": 1780.00,
      "currencyCode": "EUR"
    },
    {
      "operationCode": "OUTGOING_TRANSFER",
      "metricType": "COUNT",
      "periodType": "YEARLY",
      "committedCount": 4,
      "includedCount": 9,
      "remainingIncludedCount": 5
    }
  ]
}

Uso reale: questa è la chiamata che un'app o un portale può usare per mostrare "hai ancora 1.780 EUR disponibili questo mese" oppure "hai ancora 5 operazioni incluse". Non deve esporre eventi grezzi o movimenti contabili.

A.19 Matrice rapida dei casi coperti

Caso d'uso Configurazione principale Input richiesto al chiamante
Operazione gratuita Pricing WAIVER account, operation, amount se richiesto
Fee fissa Pricing FIXED account, operation, amount se richiesto
Fee percentuale Pricing PERCENTAGE account, operation, amount
N operazioni incluse poi fee Pricing TIERED, COUNT, periodo account, operation, idempotency su write
Volume mensile massimo Limit AMOUNT, MONTHLY account, operation, amount
Numero massimo operazioni Limit COUNT, periodo account, operation
Limite per canale ACCOUNT_CHANNEL operation con channelCode coerente
Limite per area dimensione in CUSTOM_DIMENSIONS metadata destination_area
Fee per area dimensione con isRuleEnabled metadata destination_area
Fee sopra soglia importo dimensione amount_band metadata amount_band calcolato dal chiamante
Canone da saldo medio dimensione average_monthly_balance metadata calcolato dal sistema saldo
Saldo massimo dimensione projected_balance_after_operation saldo proiettato calcolato dal sistema saldo
Profilo cliente account attribute attributo su account contract
Deroga singola dimensione limit_exception_granted metadata booleano autorizzato a monte