🎁 Bonus Node

The Bonus Node is a type of `calculation` node that awards a bonus based on different strategies

  • tiered — reward tiers based on attainment level
  • proportional — linear bonus proportional to attainment between thresholds
  • fixed — fixed amount (used when conditions are not met)

It supports target- or metric-based attainment, and optional long-term balancing (regulatory adjustments over time).


📦 JSON Representation

{
  "type": "calculation",
  "data": {
    "id": "bonus",
    "formData": {
      "type": "tiered" | "proportional" | "fixed",
      "reference_type": "target" | "metric",
      "target": {
        "id": "q1_target"
      },
      "metric": {
        "id": "customer_nps"
      },
      "tiers": [
        { "attainment": 80, "value": 1000 },
        { "attainment": 100, "value": 2000 }
      ],
      "minimum_achievement": 0.6,
      "maximum_achievement": 1.0,
      "fixed_amount": 500
    },
    "type": "calculation"
  }
}

🧾 Form Data Fields

FieldRequiredApplies toDescription
typeallStrategy used: tiered, proportional, or fixed.
reference_typeallWhether the node measures attainment from a target or metric.
target.idif reference_type = targetID of the target to measure performance against.
metric.idif reference_type = metricID of the metric to use for attainment.
tierstieredList of { attainment, value } pairs. The first tier matched is applied.
minimum_achievementproportionalMinimum threshold to start receiving a proportional bonus.
maximum_achievementproportionalMaximum threshold to cap the proportional bonus.
fixed_amountOptionalfallbackUsed when no tier or proportional bonus applies.

⚙️ Execution Logic

▶️ type = tiered

  • Attainment is calculated via target or metric.
  • Tiers are evaluated in descending order.
  • The first tier where attainment ≥ threshold is applied.
  • Bonus value = getCompensationValue(tier.value, attainment) × outcome

▶️ type = proportional

  • Only works with reference_type = target
  • If attainment >= minimum_achievement:
  • Bonus percentage = min(attainment, maximum_achievement)
  • Final value = bonus percentage × target outcome
  • If below threshold, no bonus is paid.
  • Long-term regulation is optionally applied.

▶️ type = fixed

  • A fallback if no proportional/tiered bonus applies.
  • Bonus is always fixed_amount.

🕒 Long-Term Balancing (Regulation)

If compensationRule.long_term_balancing_period is set:

  • Previous payouts are fetched for the current user.
  • Compensation is adjusted:
  • compensation_value = computed_value - total_previous_payouts
  • Tracks:
  • compensation_value_before_regulation
  • total_previous_payouts
  • regulation_period

📤 Output Variables

VariableTypeDescription
compensation_valuenumberFinal bonus after any adjustment
compensation_value_before_regulationnumber(optional) Before subtracting past payouts
bonus_percentagenumber(proportional only) Percentage applied
attainmentnumberNormalized attainment
tier_indexnumber(tiered only) Matched tier index
compensation_valuesarrayPer-profile output for team-wide nodes
target_outcomesarrayList of { profile_id, outcome } used
total_previous_payoutsnumber or arrayHistorical payouts for this compensation rule
regulation_periodstringTimeframe applied for long-term balancing
contextobjectContextual info (target/metric, period, attainment)

🧪 Example

Tiered bonus with 2 levels:

"tiers": [
  { "attainment": 80, "value": 1000 },
  { "attainment": 100, "value": 2000 }
]
  • If attainment = 0.85 (and reference is target), tier 1 is matched.
  • Final bonus: 1000 × outcome × 0.85

On this page