Skip to content

Policy engine

Every payout — from POST /v1/withdraws or the request_payout MCP tool — is evaluated by the policy engine before anything moves. There are no scopes and no per-key policy: thresholds are configured per user, and every API key belonging to that user shares the same policy.

The engine returns one of three decisions:

DecisionMeaning
allowPayout executes immediately against the bank rail
require_approvalPayout attempt is created with status: "pending_approval"; a WhatsApp/Telegram approval request is sent
denyRequest is rejected outright with 422 PAYOUT_DENIED — no approval possible

The first rule that matches returns immediately — later rules are never evaluated.

  1. KYC incompletedeny (kyc_incomplete) if the user has no linked bank-rail account yet or onboarding != "done".
  2. Invalid amountdeny (amount_invalid) if amount <= 0.
  3. Whitelist fast-pathallow if the destination CBU is in whitelist_cbus and amount <= per_tx_limit_ars. If the destination is whitelisted but exceeds the per-tx limit, evaluation continues to the next rules instead of stopping here.
  4. Absolute caprequire_approval (absolute_cap) if require_approval_above_ars > 0 and amount >= require_approval_above_ars.
  5. Per-transaction limitrequire_approval (per_tx_limit) if per_tx_limit_ars > 0 and amount > per_tx_limit_ars.
  6. Daily limitrequire_approval (daily_limit) if daily_limit_ars > 0 and daily_spent_so_far + amount > daily_limit_ars.
  7. Monthly limitrequire_approval (monthly_limit) if monthly_limit_ars > 0 and monthly_spent_so_far + amount > monthly_limit_ars.
  8. Defaultallow.

Read and write the thresholds behind these rules with GET/PUT /v1/thresholds or the get_thresholds / propose_threshold_change MCP tools:

{
"per_tx_limit_ars": 100000,
"daily_limit_ars": 300000,
"monthly_limit_ars": 2000000,
"require_approval_above_ars": 500000,
"whitelist_cbus": ["0000003100010000123456"]
}

If a user has no thresholds row yet, nuez falls back to the server defaults (env vars DEFAULT_PER_TX_LIMIT_ARS, DEFAULT_DAILY_LIMIT_ARS, DEFAULT_MONTHLY_LIMIT_ARS, DEFAULT_REQUIRE_APPROVAL_ABOVE_ARS) rather than erroring.

whitelist_cbus is a flat list of CBU/CVU strings. It only grants a fast-path to allow — it never bypasses rules 1–2, and a whitelisted destination above per_tx_limit_ars still falls through to the threshold rules like any other payout.

daily_spent_so_far and monthly_spent_so_far are computed live from SumDailySpent / SumMonthlySpent over the user’s payout attempts — there’s no separate ledger to keep in sync.