Skip to main content

Overview

Create restriction rules to control betting limits across the system. Rules can be scoped to Banca, Ventana, or User (vendedor) level with optional filters for numbers, lotteries, dates, and times.

Endpoint

POST /api/v1/restrictions
Authorization: ADMIN only

Request Body

Scope Fields (At least one required for non-lottery rules)

bancaId
string
UUID of banca (for banca-level rules)
ventanaId
string
UUID of ventana (for ventana-level rules)
userId
string
UUID of user/vendedor (for user-level rules)

Rule Type Fields

restrictionType
string
Optional label for categorizing rules (e.g., “LIMIT”, “CUTOFF”)

Number Fields

number
string | array
Specific number(s) to restrict:
  • Single number: "25" (legacy format)
  • Multiple numbers: ["00", "25", "50", "75", "99"] (max 1000)
Numbers must be 0-999 (supports TICA and MONAZOS). For batch creation, the same restriction applies to all numbers.
isAutoDate
boolean
If true, automatically updates number to match the current day of month (1-31).Use case: Restrict betting on today’s date number.Restrictions:
  • Only works with amount-based rules (maxAmount or maxTotal)
  • Cannot be used with lottery/multiplier rules
  • number field must be omitted when true

Amount Limit Fields

maxAmount
number
Maximum bet amount per jugada for this number (must be positive)
maxTotal
number
Maximum total amount per ticket (all jugadas combined, must be positive)
baseAmount
number
Base amount for dynamic limit calculation (≥ 0)Used with salesPercentage to calculate dynamic limits based on current sales.
salesPercentage
number
Percentage of current sales to add to baseAmount (0-100)Formula: effectiveLimit = baseAmount + (currentSales * salesPercentage / 100)
appliesToVendedor
boolean
If true, apply the dynamic percentage calculation per-vendedor. If false, apply globally.Only valid when salesPercentage is present.

Sales Cutoff Fields

salesCutoffMinutes
number
Minutes before sorteo draw when sales must stop (0-30)Cannot be combined with:
  • Amount limits (maxAmount, maxTotal)
  • Lottery/multiplier restrictions
  • number field

Date/Time Filters

appliesToDate
string
ISO 8601 date when rule applies (null = all dates)
appliesToHour
number
Hour (0-23) when rule applies (null = all hours)

Lottery/Multiplier Filters

loteriaId
string
UUID of specific lotteryRequired if multiplierId is provided
multiplierId
string
UUID of specific multiplierRequired if loteriaId is provided
message
string
Optional custom message (1-255 characters) to display when rule is triggered

Rule Types

1. Per-Number Amount Limit

Restrict maximum bet per jugada for specific numbers.
{
  "bancaId": "banca-uuid",
  "loteriaId": "loteria-uuid",
  "number": "25",
  "maxAmount": 5000,
  "message": "Número 25 limitado a 5000 colones"
}

2. Batch Number Restrictions

Create multiple rules for different numbers in one request.
{
  "ventanaId": "ventana-uuid",
  "loteriaId": "loteria-uuid",
  "number": ["00", "01", "25", "50", "75", "99"],
  "maxAmount": 3000
}

3. Global Ticket Limit

Restrict maximum total per ticket (all jugadas combined).
{
  "userId": "vendedor-uuid",
  "loteriaId": "loteria-uuid",
  "maxTotal": 50000
}

4. Sales Cutoff Rule

Define when sales must stop before draw.
{
  "bancaId": "banca-uuid",
  "loteriaId": "loteria-uuid",
  "salesCutoffMinutes": 10
}

5. Dynamic Limit (Sales-Based)

Limit increases with current sales volume.
{
  "bancaId": "banca-uuid",
  "number": "13",
  "baseAmount": 2000,
  "salesPercentage": 10,
  "appliesToVendedor": false,
  "maxAmount": 10000
}
How it works:
  • Base limit: 2000
  • If current sales for “13” = 50000, add 10% = 5000
  • Effective limit: 2000 + 5000 = 7000 (capped at maxAmount 10000)

6. Auto-Date Restriction

Automatically restrict betting on today’s date.
{
  "bancaId": "banca-uuid",
  "loteriaId": "loteria-uuid",
  "isAutoDate": true,
  "maxAmount": 3000
}
Behavior: If today is March 15, this restricts number “15” to 3000. Tomorrow it automatically switches to “16”.

7. Lottery/Multiplier Specific Rule

Block or limit specific lottery + multiplier combinations.
{
  "loteriaId": "loteria-uuid",
  "multiplierId": "multiplier-uuid",
  "maxAmount": 10000
}
Note: Lottery/multiplier rules can be global (no bancaId/ventanaId/userId).

8. Event-Specific Restriction

Apply restrictions only on specific dates/times.
{
  "bancaId": "banca-uuid",
  "loteriaId": "loteria-uuid",
  "number": "13",
  "maxAmount": 1000,
  "appliesToDate": "2025-12-25T00:00:00.000Z",
  "appliesToHour": 12,
  "message": "Restricción especial de Navidad"
}

Response

success
boolean
Indicates if the request was successful
data
object | array
Created restriction rule(s)For single number: returns one object For batch creation: returns array of objects

Examples

curl -X POST "https://api.example.com/api/v1/restrictions" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "bancaId": "550e8400-e29b-41d4-a716-446655440000",
    "loteriaId": "loteria-uuid",
    "number": "25",
    "maxAmount": 5000
  }'

Validation Rules

Scope requirement: At least one of bancaId, ventanaId, or userId is required UNLESS the rule is a lottery/multiplier restriction (which can be global).
Sales cutoff rules (salesCutoffMinutes) cannot be combined with:
  • Amount limits (maxAmount, maxTotal)
  • Lottery/multiplier restrictions
  • Number filters
If you specify loteriaId, you must also specify multiplierId, and vice versa.
isAutoDate rules:
  • Require maxAmount or maxTotal
  • Cannot have number field
  • Cannot be used with lottery/multiplier rules
baseAmount and salesPercentage:
  • Can only be used with amount-based rules (maxAmount or maxTotal)
  • salesPercentage must be 0-100
  • baseAmount must be ≥ 0
  • appliesToVendedor only valid when salesPercentage is present
Numbers must be:
  • 1-3 digits (0-999)
  • Valid range: 0 to 999 (supports TICA 0-99 and MONAZOS 100-999)
  • No duplicates in batch arrays
  • Max 1000 numbers per batch request

Priority Levels

Restrictions follow hierarchical priority:
  1. USER (vendedor): Priority 100
  2. VENTANA: Priority 10
  3. BANCA: Priority 1
First matching rule wins during ticket validation.

Error Responses

{
  "success": false,
  "error": "Validation failed",
  "issues": [
    {
      "path": ["(root)"],
      "message": "Debe indicar bancaId, ventanaId o userId (al menos uno)."
    }
  ]
}

List Restrictions

View all restriction rules

Update Restriction

Modify existing rule

Delete Restriction

Soft delete a rule

Implementation Details

From src/api/v1/controllers/restrictionRule.controller.ts:10-13:
async create(req: AuthenticatedRequest, res: Response) {
  const rule = await RestrictionRuleService.create(req.user!.id, req.body);
  res.status(201).json({ success: true, data: rule });
}
Validation is performed using Zod schemas in src/api/v1/validators/restrictionRule.validator.ts:47-194.

Build docs developers (and LLMs) love