MotifEngineOpen console(opens in a new tab)

Your product already has players.

MotifEngine turns what your users already do into XP, achievements, missions, points and rewards. Your backend sends events, your team publishes the rules, and every reward lands in a ledger that never counts twice.

Type
Engagement and loyalty engine
License
Open source
Integration
REST · OpenAPI 3.0
Scope
Environment → user
Event triggerPOST /v1/events
{
  "event_type": "order.completed",
  "user_id": "you",
  "payload": {
    "order_id": "order-1001",
    "total": 129.9,
    "currency": "USD",
    "payment_status": "paid"
  }
}
  1. Waiting for a signal. Pick an event and fire it.

Simulated in your browser · same semantics as the API

[Scroll to continue]

Engagement logic usually hides in cron jobs, spreadsheets and one-off scripts. MotifEngine gives it one home: trusted events in, published rules in the middle, ledgered rewards out.

  • One receipt per event id
  • One effect per rule version and action
  • One append-only ledger per currency

One event. Five moves.

Follow a single order from your backend to a reward the customer can hold. Each move is a real part of the engine, shown with the shape it has in the API.

Your backend sends a fact.

A trusted event arrives with a stable event id. It is validated against an immutable contract version, deduplicated, written with an outbox row, and answered with a 202 receipt before any effect runs.

Shape in the APIPOST /v1/events
{
  "event_id": "order-1001-completed",
  "event_type": "order.completed",
  "user_id": "user-42",
  "payload": {
    "total": 129.90,
    "payment_status": "paid"
  }
}

A published rule decides.

Rules are data, not customer code: when an event type arrives, if a restricted condition holds, then typed actions run. Drafts never execute. Publishing freezes a version, and optional UTC windows bound a campaign.

Shape in the APIPOST /v1/admin/rules
{
  "event_type": "order.completed",
  "conditions": {"eq": ["$.payment_status", "paid"]},
  "actions": [
    {"type": "award_xp", "amount": 25},
    {"type": "award_points",
     "currency": "loyalty", "amount": 50}
  ]
}

Progress is not money.

XP accumulates per external user and resolves to the level whose threshold it has reached. Missions count matching events toward a target; achievements unlock after a required count. None of it is spendable.

Shape in the APIGET /v1/users/{id}/progression
{
  "total_xp": 275,
  "level": 3,
  "level_name": "Regular",
  "next_level_xp": 500
}

Every balance is a ledger.

Each currency keeps its own append-only history. Awards, spends, expiring lots and conversions are entries with idempotency keys, so a retry can never pay twice and a correction never deletes the original row.

Shape in the APIGET /v1/users/{id}/points/transactions
{
  "currency": "loyalty",
  "amount": 50,
  "type": "award",
  "idempotency_key":
    "order-1001-completed:completed_order_reward@v3:1"
}

Redemption you can recover.

A reward is free or costs one active currency. Each redemption reserves points, records every provider attempt, and stays in delivering when the outcome is unknown, until a status check or retry settles it.

Shape in the APIPOST /v1/rewards/{id}/redemptions
reserved → delivering
delivering → fulfilled

timeout → outcome unknown
  points stay reserved
status check → fulfilled

Insert coin.

Four proofs you can play. Each one runs the engine’s semantics in your browser, and each one pays out an achievement when you clear it.

Give 50 loyalty points to paid orders of 120 or more. Nothing else.

If · $.total
{
  "event_type": "order.completed",
  "conditions": {"gt": ["$.total", 100]},
  "actions": [{"type": "award_points", "currency": "loyalty", "amount": 50}]
}
order.completed streamnot evaluated
  1. order-200145.00paid—
  2. order-2002120.00paid—
  3. order-200388.00paid—
  4. order-2004260.00paid—
  5. order-2005119.00paid—
  6. order-2006150.00refunded—
  7. order-2007199.00pending—
  8. order-2008131.00paid—
  9. order-200975.00refunded—
  10. order-2010121.00paid—

Everything in the engine.

Ten parts, one contract. Each row names the endpoint where it lives, so your engineers can check every word.

  • Events and contracts[POST /v1/events]

    Receive each fact once. Bounded payloads are validated against immutable JSON Schema versions, deduplicated by event id, and committed with an outbox row before the worker sees them.

  • Rules and actions[POST /v1/admin/rules]

    When, if, then, stored as data. Conditions use all, any, exists, eq, neq, gt, gte, lt and lte; actions award XP, award points or log. Every published version stays readable for audit.

  • Campaigns and schedules[starts_at · ends_at]

    Copy a UTC window into a rule version to run a weekend bonus without a deploy. Campaigns and goals measure a bounded activity by event and unique-user counts.

  • XP, levels, missions, achievements[GET /v1/users/{id}/profile]

    Cumulative XP thresholds name levels. Missions track a target count, achievements unlock after a required count, and streaks read active UTC days for any event type.

  • Point currencies and ledger[POST /v1/points/conversions]

    Run loyalty points, coins and credits side by side. Each has an append-only ledger with expiring lots, atomic spending and conversion at a versioned rate.

  • Rewards and providers[POST /v1/rewards/{id}/redemptions]

    Free or paid rewards, reservations, idempotency headers sent to HTTP providers, attempt history, and reconciliation for outcomes that are still unknown.

  • Environments and credentials[POST /v1/admin/credentials]

    The server scopes every request to one environment, such as sandbox or production, so tests never touch live balances. Integration keys are hashed, shown once, and can be rotated or revoked.

  • REST API and OpenAPI[openapi 3.0.3]

    A versioned REST contract with an OpenAPI description. Any HTTP client works from your backend; there is no SDK to adopt and no widget you must ship.

  • Analytics and measurement[GET /v1/admin/analytics]

    Goals, campaigns, metrics, funnels, retention cohorts, behavioural segments and experiment reports measure outcomes. They describe what happened; rules decide what happens.

  • Security and operations[GET /v1/admin/diagnostics]

    Expiring hashed sessions, role-based console access, an append-only audit stream, rate limits, request ids, Prometheus metrics and a diagnostics snapshot of the pipeline.

Made for products with users.

The same loop, six genres. Every recipe is a real rule shape from the scenario cookbook.

Reward the second purchase.

  1. Whenorder.completed
  2. If · then
    {"eq": ["$.customer_order_number", 2]}
    → award_points loyalty 100
  3. Effect

    +100 loyalty, once per order

The rule reads the payload. Your order service counts purchases and sends the number as a trusted field.

Straight answers.

A simulation of MotifEngine’s event, rule, ledger and redemption semantics, running in your browser. Nothing is sent to a MotifEngine API, and your run is stored only in this browser.

Once. Your backend sends events over REST with an environment-scoped key. After that, currencies, levels, missions, achievements, rewards and automations are configured in the console.

No. MotifEngine is API-first: you design the player-facing interface and read profiles, balances, missions, achievements and progression from the API.

No. XP is progression and is never spent. Point currencies are spendable balances with their own ledgers, expiration and conversion rates.

The redemption stays in delivering and its points stay reserved. A provider status check or a retry with the same redemption id settles it; only a confirmed failure releases the points.

MotifEngine is open source, and you can run the full stack locally with Docker Compose. Public pricing has not been set.

Press start.

Create a workspace, register your first event, publish a rule. Your players are already waiting.

Or run the whole stack locally: make dev-docker

Level
01 Starter
XP
0
Achievements
0/16
Events processed
0

MotifEngine runtime · power-on self test

  1. 001Open workspace··
  2. 002Load event contracts
  3. 003Compile published rules
  4. 004Warm point ledgers
  5. 005Arm achievements
  6. 006Connect reward providers
  7. 007Start worker
  8. 008Ready player