Skip to main content

MagicWeave SDK: Player Events (apps/client/client_game)

This guide is for game developers integrating gameplay event tracking and reward evaluation from the MagicWeave SDK.

The client_game module lets your game:

  • send player gameplay events
  • evaluate those events against server-side game definitions
  • progress event sequences
  • credit gems when a sequence is fully matched

Base URL and Route Prefix

Use one of these deployment styles:

  • Split client API deployment: http://localhost:8001
  • Combined deployment: http://localhost:8000/client

Event routes are under:

  • /events

Current endpoint:

  • POST /events/record

Required Authentication and Headers

All event endpoints require:

  • x-client-id: <your_project_client_id>
  • x-client-secret: <your_project_client_secret>
  • Authorization: Bearer <magicweave_access_token>
  • Content-Type: application/json

The authenticated user must have client.game permission.

Endpoint: Record Event

POST /events/record

Request body:

{
"definition_key": "Ab12Cd34",
"event_name": "game.level.completed",
"event_data": {
"level": 3,
"result": "win"
},
"idempotency_key": "session-777:event-15"
}

Field rules:

  • definition_key: exactly 8 alphanumeric characters
  • event_name: required string
  • event_data: JSON object (default {})
  • idempotency_key: required string; use a unique key per event send attempt

Reference: Record event

How Matching Works

The backend maps your event to a server-defined GameDefinition for your project and then evaluates sequence progress.

Important behavior:

  • definition_key is normalized to uppercase server-side.
  • A definition has a trigger_sequence of steps.
  • Each step match requires:
    • exact event_name match
    • all condition key/value pairs to match in event_data
  • Extra keys in event_data are allowed.
  • Only one active sequence is allowed per user per project at a time.

Typical Responses

The endpoint returns a dynamic JSON object depending on evaluation result.

Sequence started

{
"status": "sequence_started",
"definition": "daily-win-sequence"
}

Intermediate step accepted

{
"status": "recorded",
"definition": "daily-win-sequence"
}

Final step matched and reward credited

{
"status": "matched",
"rewarded": true,
"gems_credited": 3,
"new_balance": 156,
"transaction_id": 9001
}

Idempotent replay of already processed event

{
"status": "matched",
"rewarded": true,
"gems_credited": 3,
"new_balance": 156,
"transaction_id": 9001,
"idempotent": true
}

Rejected examples

{
"status": "rejected",
"reason": "unknown_definition"
}
{
"status": "rejected",
"reason": "wrong_step"
}
{
"status": "rejected",
"reason": "sequence_in_progress",
"active_definition": "other-sequence",
"expires_in_seconds": 120
}
{
"status": "rejected",
"reason": "sequence_too_fast",
"retry_after_seconds": 8
}
{
"status": "rejected",
"reason": "constraint_failed"
}

Rejection Reasons You Should Handle

  • unknown_definition: no game definition found for provided key
  • invalid_definition_sequence: definition has invalid trigger sequence
  • sequence_in_progress: another definition sequence is currently active
  • wrong_step: event does not match the next expected sequence step
  • sequence_too_fast: completed sequence faster than configured minimum
  • constraint_failed: definition-level constraints (for example cooldown) failed

Idempotency Guidance

Idempotency is enforced per project and idempotency_key.

Recommended approach:

  • Generate one stable idempotency key per emitted gameplay event.
  • Reuse same key on retries of the same event.
  • Never reuse the same key for a different gameplay event.

Suggested format:

  • <session-id>:<event-index> or <match-id>:<server-tick>

Reward and Wallet Behavior

On final sequence match:

  • gems are credited to player's wallet
  • a wallet transaction is created (description like reward:<definition-slug>)
  • response returns gems_credited, new_balance, and transaction_id
  • per-definition cooldown is updated

cURL Example

curl -X POST "http://localhost:8001/events/record" \
-H "x-client-id: <client-id>" \
-H "x-client-secret: <client-secret>" \
-H "Authorization: Bearer <access-token>" \
-H "Content-Type: application/json" \
-d '{"definition_key":"Ab12Cd34","event_name":"game.level.completed","event_data":{"level":3,"result":"win"},"idempotency_key":"session-777:event-15"}'

Prerequisite: Configure Game Definitions (Admin API)

/events/record depends on game definitions configured for your project (including definition_key, sequence steps, reward amount, and cooldown/time constraints).

These are managed through internal admin endpoints under:

  • /game-definitions/{org_id}/{project_id}/...

Integration Notes for Game Teams

  • Keep event naming stable and versioned (game.level.completed.v1) when needed.
  • Ensure client event payload keys exactly match definition conditions.
  • Send events in deterministic order to avoid wrong_step outcomes.
  • Persist and retry unsent events with same idempotency key for network resilience.
  • Use response status to drive UX (progress indicator, reward toast, cooldown hint).