Amba

Event-triggered Currency Grants

Grant currency automatically when a user action fires — no admin keys exposed to the client.

Connect user behavior directly to your economy. When Amba.events.track() fires, the server checks for matching grant rules and credits the user's balance automatically — no admin credentials needed on the client side.

Quickstart

Step 1 — Create the currency (if you haven't already)

// Via MCP in your dev shell or agent
amba_currencies_create({
  project_id: 'proj_...',
  code: 'calm_points',
  name: 'Calm Points',
});

Step 2 — Provision a grant rule

// Grant 10 calm_points every time session.completed fires
amba_currency_grant_rules_create({
  project_id: 'proj_...',
  currency_key: 'calm_points',
  event_name: 'session.completed',
  grant_amount: 10,
});

Step 3 — Track the event from your app

await Amba.events.track('session.completed', { minutes: 1 });
// → +10 calm_points granted automatically
// → balance updated on next Amba.currencies.getBalances() call

That's it. No server-side code needed.

Grant modes

Flat grant

Grant a fixed amount on every qualifying event.

amba_currency_grant_rules_create({
  currency_key: 'calm_points',
  event_name: 'session.completed',
  grant_amount: 10, // always +10
});

Property-scaled grant

Scale the grant by a numeric property on the event. Useful for distance, duration, or score-based rewards.

amba_currency_grant_rules_create({
  currency_key: 'calm_points',
  event_name: 'session.completed',
  grant_property: 'minutes', // read from event properties
  grant_multiplier: 2, // 2 points per minute
});
// 10-minute session → +20 calm_points
await Amba.events.track('session.completed', { minutes: 10 });

The result is floor(property_value × multiplier). If the property is absent or non-numeric, the grant is skipped silently.

Daily cap

Prevent farming with max_per_day. The cap is enforced per user per UTC day.

amba_currency_grant_rules_create({
  currency_key: 'calm_points',
  event_name: 'session.completed',
  grant_amount: 10,
  max_per_day: 50, // cap at 50 points/day
});

Once a user reaches the daily cap, further events for that rule grant 0 points until UTC midnight resets the counter.

Multiple rules

Multiple rules can target the same event. All matching enabled rules fire independently — their grants are summed.

// Both rules fire on "session.completed"
amba_currency_grant_rules_create({
  currency_key: 'calm_points',
  event_name: 'session.completed',
  grant_amount: 10,
});
amba_currency_grant_rules_create({
  currency_key: 'streak_tokens',
  event_name: 'session.completed',
  grant_amount: 1,
});

Managing rules

List rules

const rules = await amba_currency_grant_rules_list({ project_id: 'proj_...' });

Disable a rule (without deleting it)

Rules don't have an update endpoint yet — delete and re-create to change parameters. To pause a rule quickly, delete it; existing ledger history is preserved.

Delete a rule

await amba_currency_grant_rules_delete({
  project_id: 'proj_...',
  rule_id: 'rule_...',
});

Deleting a rule stops it from firing on future events. Historical grants in the transaction ledger are not affected.

Read the balance

After events fire, read the updated balance with the currencies SDK:

const balances = await Amba.currencies.getBalances();
const calmPoints = balances.find((b) => b.currency_code === 'calm_points');
console.log(calmPoints?.balance); // e.g. 50

How it works

  1. Amba.events.track(name, properties) sends the event to the API.
  2. The API writes the event to the database, then checks for enabled grant rules matching the event name.
  3. For each matching rule, the server runs a serialized transaction:
    • Reads the user's current balance with a row-level lock (prevents concurrent grant races).
    • Applies the daily cap if configured.
    • Credits the balance and writes an audit entry.
  4. The getBalances() call reflects the new balance immediately.

Grants are applied server-side — client code never touches admin credentials.


See Virtual Currencies for details on currency definitions, balance caps, and auto-recharge.

On this page