Actions
Actions are the heartbeat of RapidMule. Every gamification journey, every badge earned, every reward issued - it all starts with an Action. Think of Actions as the events happening in your application that you want to track, measure, and reward.
What is an Action?
An Action represents a user activity or system event from your application. When something meaningful happens in your system, you send an Action to RapidMule:
- A user completes a purchase → send a
purchaseaction - A user logs in → send a
loginaction - A user places a bet → send a
place_betaction - A user creates content → send a
create_postaction
Once RapidMule receives an Action, the engine automatically evaluates it against all active Conditions you've configured in your dashboard. If the Action satisfies a Condition's requirements (Challenges + Filters), the corresponding Badge or Trigger is awarded, and Deliverables are issued.
Anatomy of an Action
Every Action sent to RapidMule has these key components:
Required Fields
| Field | Purpose | Example |
|---|---|---|
name | Identifies the type of action | "purchase", "login", "complete_workout" |
playerId | Identifies the user performing the action | "user-abc-123" |
referenceId | Unique identifier for this specific action instance | "order-f4a7c1b9-3e5d" |
Optional Fields
| Field | Purpose | When to Use |
|---|---|---|
timestamp | When the action occurred (Unix milliseconds) | When tracking historical events or ensuring correct chronological order |
multiplier | Multiplies the action's impact | For special events, promotions, or VIP users (e.g., "Double Points Weekend") |
details | Array containing Action Objects | When you need to pass contextual data about the action |
Action Objects (Details)
Action Objects are custom properties you attach to an Action to provide rich context. They're stored in the details array and enable powerful filtering and tracking capabilities.
Without Action Objects, you can only track "a purchase happened." With Action Objects, you can track "a $149.99 electronics purchase with credit card from mobile app" - and filter/reward based on these details!
- E-commerce Purchase
- Fitness Workout
- Social Content Creation
- Betting/Gaming
{
"name": "purchase",
"referenceId": "order-456",
"playerId": "user-123",
"details": [
{
"name": "amount",
"value": "99.99"
},
{
"name": "currency",
"value": "USD"
},
{
"name": "category",
"value": "electronics"
},
{
"name": "items_count",
"value": "2"
},
{
"name": "payment_method",
"value": "credit_card"
},
{
"name": "is_first_purchase",
"value": "false"
}
]
}
What you can do with this:
- Award "Electronics Enthusiast" badge when
category = "electronics" - Give bonus points when
amount > 100 - Track different rewards for
payment_method
{
"name": "complete_workout",
"referenceId": "workout-001",
"playerId": "user-sarah-fitness",
"details": [
{
"name": "workout_type",
"value": "cardio"
},
{
"name": "duration_minutes",
"value": "30"
},
{
"name": "calories_burned",
"value": "250"
},
{
"name": "difficulty",
"value": "beginner"
},
{
"name": "completed_at_gym",
"value": "true"
}
]
}
What you can do with this:
- Separate badges for
workout_type(cardio, strength, yoga) - Bonus rewards when
duration_minutes >= 60 - Filter only
completed_at_gym = truefor "Gym Regular" badge
{
"name": "create_post",
"referenceId": "post-12345",
"playerId": "user-alex-456",
"details": [
{
"name": "post_id",
"value": "post-12345"
},
{
"name": "title",
"value": "How to optimize React performance?"
},
{
"name": "category",
"value": "web-development"
},
{
"name": "word_count",
"value": "450"
},
{
"name": "has_code",
"value": "true"
},
{
"name": "tags",
"value": "react,performance,optimization"
}
]
}
What you can do with this:
- Award category-specific badges (
category = "web-development") - Bonus for high-quality content (
word_count > 300+has_code = true) - Track expertise in specific tags
{
"name": "place_bet",
"referenceId": "bet-12345",
"playerId": "player-sarah-001",
"details": [
{
"name": "bet_amount",
"value": "50"
},
{
"name": "currency",
"value": "USD"
},
{
"name": "event_type",
"value": "football"
},
{
"name": "match",
"value": "Arsenal vs Chelsea"
},
{
"name": "odds",
"value": "2.5"
},
{
"name": "bet_type",
"value": "single"
}
]
}
What you can do with this:
- Leaderboards filtered by
event_type = "football" - Different rewards for
bet_type(single, parlay, system) - Track high-roller behavior with
bet_amount
The Power of referenceId (Idempotency)
The referenceId is your safety net. It ensures that if you accidentally send the same Action twice, RapidMule won't process it twice.
Without referenceId:
User completes order-123
→ Send action to RapidMule ✅
→ Network hiccup, timeout
→ Your system retries
→ Send action again ❌
→ User gets reward TWICE! 🐛
With referenceId:
User completes order-123
→ Send action with referenceId: "order-123" ✅
→ Network hiccup, timeout
→ Your system retries
→ Send action again with referenceId: "order-123" ✅
→ RapidMule: "Already processed, ignoring" ✅
→ User gets reward ONCE! ✅
Using Timestamp
By default, RapidMule uses the server's current time when an Action is received. But sometimes you need to specify the exact moment the event occurred:
When to use timestamp:
- Backfilling historical data
- Batch processing events
- Ensuring correct order for time-sensitive challenges
{
"name": "login",
"referenceId": "login-jan-15",
"playerId": "user-123"
}
The Multiplier Field
The multiplier field scales the impact of an Action. By default, it's 1.0, but you can increase it for special circumstances:
Example Use Cases:
- Double Points Weekend:
{
"name": "purchase",
"referenceId": "order-456",
"playerId": "user-123",
"multiplier": 2.0, // Everything doubles!
"details": [...]
}
- VIP Customer Bonus: Set multiplier to 1.5 for VIP users
- Special Event: Set multiplier to 3.0 during special events like Black Friday
Multipliers affect point calculations and can impact leaderboards. Use them intentionally and document when/why they're applied.
Common Action Patterns
Pattern 1: Simple Milestone Tracking
{
"name": "login",
"referenceId": "login-2025-01-15",
"playerId": "user-123"
}
Best for: Tracking occurrences (login streaks, visit counts)
Pattern 2: Value-Based Tracking
{
"name": "deposit",
"referenceId": "deposit-txn-456",
"playerId": "user-123",
"details": [
{
"name": "amount",
"value": "100.00"
},
{
"name": "currency",
"value": "USD"
}
]
}
Best for: Sum challenges ($1000 total deposits), leaderboards
Pattern 3: Complex Event Tracking
{
"name": "complete_order",
"referenceId": "order-789",
"playerId": "user-123",
"details": [
{
"name": "order_total",
"value": "299.99"
},
{
"name": "category",
"value": "electronics"
},
{
"name": "shipping_method",
"value": "express"
},
{
"name": "discount_applied",
"value": "true"
},
{
"name": "discount_amount",
"value": "30.00"
}
]
}
Best for: Multi-dimensional filtering, detailed analytics
Best Practices
1. Name Actions Consistently
- ✅ Good: Clear, consistent naming like "purchase", "login", "complete_workout", "create_post"
- ❌ Bad: Inconsistent, unclear naming like "buy", "Buy", "BUY_ITEM", "purchase-completed"
2. Include Rich Action Objects
- ✅ Good: Rich context with multiple fields like amount, currency, category, payment_method, is_mobile
- ❌ Bad: Minimal context with only basic fields like amount
3. Use Deterministic referenceIds
- ✅ Good: Use existing system IDs like order.id ("order-f4a7c1b9")
- ❌ Bad: Generate random ID each time like uuid.v4() (defeats idempotency!)
4. Handle Errors Gracefully
Always check response codes and handle duplicate actions (error code 2601) appropriately. Log other errors and implement retry logic as needed.
Next Steps
- Learn how Conditions evaluate your Actions
- See the API Actions Endpoint for complete technical documentation