Auto-ticket expressions
An auto-ticket expression is a small formula that returns one number: the total number of satoshis to allocate to a ticket, including the ticket fee. The formula can use the payment amount and the current fees, so it can express fixed budgets, percentages, caps, minimums, and conditional pricing without application code.
Core evaluates the expression once for each confirmed payment received by an auto-ticket address. This page documents the expression language and exact evaluator. For the payment-address lifecycle, confirmations, metadata, and monitoring, start with the auto-ticket deposit address guide.
budget = FLOOR(your formula); 0 ≤ budget ≤ net_amountthe returned number is floored, then checked against the available net amount and ticket feeFour values in, one budget out.
Every value is a number of satoshis. Variable names are case-insensitive, soNET_AMOUNT and net_amount are equivalent.
gross_amountThe full confirmed payment before the deposit fee is deducted.
deposit_feeThe amount charged to process the payment. It is capped at the gross amount, so
net_amountcan never be negative.net_amountThe amount available for the ticket budget and balance remainder. It is always
gross_amount - deposit_fee.ticket_feeThe flat fee for creating one ticket, snapshotted for this evaluation. A budget must be greater than this fee to leave a positive contribution.
Example: allocate 80% of the net payment
For NET_AMOUNT * 0.8, assume a payment of 100,000 sats, a deposit fee of 58 sats, and a ticket fee of 100 sats:
gross_amount = 100,000net_amount = 100,000 − 58 = 99,942budget = FLOOR(99,942 × 0.8) = 79,953ticket contribution = 79,953 − 100 = 79,853balance remainder = 99,942 − 79,953 = 19,989The formula returns the 79,953-sat budget. Core, not the expression, subtracts the ticket fee and calculates the balance remainder.
The playground runs the real evaluator.
Change the four input values, write an expression, and inspect the exact returned budget, ticket contribution, and balance remainder. The playground uses the same parser, floating-point arithmetic, flooring, range checks, and error messages as Core.
Sample amounts in sats. Real deposits use the fees Core has configured at confirmation time; the deposit fee is capped at the gross deposit.
The budget is 5,000 sats: 100 pay the ticket fee, 4,900 become the ticket's contribution, and 4,942 stay as balance.
- Deposit fee58
- Ticket fee100
- Contribution4,900
- Balance4,942
- Formula returns5,000
- Floor5,000
- Within 0…9,942?5,000 — yesthe ticket budget
- Above the 100-sat fee?yes — ticket
Solid: sats that play at each deposit size. Dashed: the most that could play there (net amount minus the ticket fee). The marker is the sample deposit above.
The formula travels in one field when you create the deposit address: autoTicket.expression on POST /api/partners/{partnerPayoutAddress}/deposit-addresses. It is validated there and immutable afterwards.
{
"id": "018f58d2-2800-4000-8000-000000000457",
"metadata": {
"orderId": "private-order-123"
},
"autoTicket": {
"expression": "MIN(net_amount, 5000)",
"metadata": {
"orderReference": "public-order-123"
}
}
}Small on purpose.
Four variables, seven numeric functions, arithmetic, comparisons, and an eager IF. No loops, no strings, no state — every valid formula reads four numbers and halts with one. Names and keywords are case-insensitive. Numbers use IEEE-754 binary64, with integer and decimal forms like 0.75 plus scientific forms like 1.5e3. Calculations can produce infinities and NaN. TRUE andFALSE exist only for conditions.
MIN(a, …)Returns the smallest argument. Commonly used to cap a ticket budget.MIN(9942, 5000) → 5000MAX(a, …)Returns the largest argument. Commonly used to set a budget floor.MAX(1000, 250) → 1000ABS(x)Absolute value.ABS(-40) → 40CLAMP(x, lo, hi)x bounded into lo…hi. Bounds that cross fail at runtime.CLAMP(12000, 0, 5000) → 5000FLOOR(x)Round down toward negative infinity.FLOOR(7456.5) → 7456CEIL(x)Round up toward positive infinity.CEIL(7456.1) → 7457ROUND(x)Nearest integer, halves away from zero.ROUND(2.5) → 3IF(cond, then, else)Eager — the condition and both numeric branches are evaluated.IF(9942 > 5000, 5000, 0) → 5000Precedence, strongest first
- binds first
( … )Grouping — the innermost group is evaluated first. - 2
^Exponent, right-associative: 2 ^ 3 ^ 2 is 512, not 64. - 3
+x, -xUnary sign. - 4
*, /, %Multiply, divide, modulo with IEEE-754 binary64 behavior. - 5
+, -Add, subtract. - 6
=, ==, !=, <, <=, >, >=Numeric comparison to a boolean. Chains like a < b < c are rejected. - 7
NOTBoolean negation. - 8
ANDBoolean and. Both operands are evaluated. - binds last
ORBoolean or. Both operands are evaluated.
Types never mix: arithmetic refuses booleans, conditions refuse bare numbers, and the finished formula must return a number — a bare comparison is rejected when the address is created. Infinities and NaN can flow through intermediate calculations, but the final floored budget must be a finite safe integer from zero through net_amount. Use MIN, MAX, or CLAMP when you want explicit saturation.
How Core interprets the result.
The expression language uses IEEE-754 binary64 arithmetic, but a ticket budget must end as a finite whole-satoshi value within the available net amount.
- Parse and type-check
Unknown names, incorrect function arguments, type mixing, and a boolean final value reject the expression. Syntax errors include their character position.
- Evaluate every branch
Functions and operators use binary64 numbers. Logical operands and both branches of
IFare evaluated eagerly; do not rely on short-circuiting to hide an invalid calculation. - Floor the returned number
Core applies
FLOORto the final numeric result. Intermediate calculations may be fractional, but the resulting budget is always a whole number of satoshis. - Check the budget range
The floored result must be finite and satisfy
0 ≤ budget ≤ net_amount. Core does not silently clamp an out-of-range result. - Apply the ticket fee
A budget greater than
ticket_feeleaves a positive ticket contribution. A smaller valid budget or an invalid result does not create a ticket; the address guide explains the resulting payment states. - Enforce expression limits
Source is limited to 500 characters, 256 syntax nodes, and 32 nesting levels. These limits are checked before the expression is stored.
Store the finished expression.
Send the validated source text as autoTicket.expression when creating an auto-ticket deposit address. The stored expression is immutable; create another address when the formula needs to change.