BricqsBricqs

Events ingestion

Events are the only entry point for action data. POST one event, the rules engine fans it out to challenges, contests, and progression. This page covers the three ingestion endpoints, idempotency, batching, and retries.

Last updatedMay 2026

Key takeaways

Quick read
  • Three endpoints: single (async), batch (async), sync (slower but returns evaluation results).
  • Always include an idempotency_key. Retries should not double-credit.
  • Soft validation: unknown event types and attributes are accepted with a warning, never rejected.
  • Batch up to 500 events per request. Above that, stream them serially.
  • Sync is for client-driven flows that need an immediate response (challenge advanced, points granted). Async is the default.

Endpoints

Three ways to send events

POST /ingest/events

Async single event. Default. Returns 202 immediately; the rules engine processes it within 100 to 500ms.

POST /ingest/events/batch

Async batch. Up to 500 events. Returns 202 with per-event idempotency status.

POST /ingest/events/sync

Synchronous. Returns the rules engine evaluation (challenges advanced, points granted) in the response. Higher latency; use sparingly.

Single event

The default path

One event, one POST. The rules engine processes it asynchronously. Most integrations use this.

POST /api/v1/ingest/events·bash
curl -X POST https://api.bricqs.co/api/v1/ingest/events \
  -H "Authorization: Bearer bq_live_admin_..." \
  -H "X-Bricqs-Tenant: tenant_brand_xyz" \
  -H "Content-Type: application/json" \
  -d '{
    "participant_id": "p_8a3f",
    "event_type": "purchase_completed",
    "attributes": {
      "amount": 1250,
      "currency": "INR",
      "category": "skincare",
      "items": ["sku_42", "sku_71"]
    },
    "occurred_at": "2026-04-30T10:42:00Z",
    "idempotency_key": "p_8a3f:order_4271",
    "source": "checkout-service"
  }'

# response
HTTP/1.1 202 Accepted
{
  "event_id": "evt_01HW...",
  "duplicate": false
}

Idempotency

The single most important field

Networks fail. Clients retry. Without an idempotency key, a flaky network can double-credit the user. With one, every retry is safe.

text
Recommended format: <participant_id>:<event_subject>:<period>

Examples:
  p_8a3f:order_4271                  one-shot purchase
  p_8a3f:streak_tick:2026-04-30      daily streak (one per day)
  p_8a3f:q_fit_basics:2026-04-30     quiz attempt (one per day per quiz)
  p_8a3f:referral:user_invited:p_91x referral signup

Behavior:
  Same key inside 24 hours = duplicate, ignored. Returns 200 with duplicate: true.
  Different attributes with same key = first write wins. Following requests are dropped.
  No key supplied = no dedup. Strongly discouraged.

Batch

Up to 500 events in one POST

Use batch when ingesting historical data, replaying from a queue, or fanning out across many participants in tight loops.

POST /api/v1/ingest/events/batch·bash
curl -X POST https://api.bricqs.co/api/v1/ingest/events/batch \
  -H "Authorization: Bearer bq_live_admin_..." \
  -H "X-Bricqs-Tenant: tenant_brand_xyz" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      {
        "participant_id": "p_8a3f",
        "event_type": "lesson_completed",
        "attributes": { "lesson_id": "l_001" },
        "idempotency_key": "p_8a3f:l_001"
      },
      {
        "participant_id": "p_91xx",
        "event_type": "lesson_completed",
        "attributes": { "lesson_id": "l_002" },
        "idempotency_key": "p_91xx:l_002"
      }
      // up to 500 events
    ]
  }'

# response
HTTP/1.1 202 Accepted
{
  "accepted": 487,
  "duplicates": 13,
  "results": [
    { "idempotency_key": "p_8a3f:l_001", "event_id": "evt_01HW...", "duplicate": false },
    { "idempotency_key": "p_91xx:l_002", "event_id": null, "duplicate": true }
    // ...
  ]
}

Sync

When the client needs an immediate result

The default async path is fast (100 to 500ms processing) but the client does not see the rules-engine outcome in the response. Use sync when the UI needs to know what changed.

POST /api/v1/ingest/events/sync·bash
curl -X POST https://api.bricqs.co/api/v1/ingest/events/sync \
  -H "Authorization: Bearer bq_live_admin_..." \
  -H "X-Bricqs-Tenant: tenant_brand_xyz" \
  -H "Content-Type: application/json" \
  -d '{
    "participant_id": "p_8a3f",
    "event_type": "quiz_completed",
    "attributes": { "quiz_id": "q_fit_basics", "score": 100 },
    "idempotency_key": "p_8a3f:q_fit_basics:2026-04-30"
  }'

# response (synchronous evaluation)
HTTP/1.1 200 OK
{
  "event_id": "evt_01HW...",
  "results": {
    "points_granted": 50,
    "tier_changed": null,
    "challenge_progress": [
      {
        "challenge_id": "fitness_30day",
        "objective_id": "complete_5_quizzes",
        "from": 2,
        "to": 3,
        "completed": false
      }
    ],
    "badges_earned": [],
    "contest_score_delta": [
      { "contest_id": "april_quiz_cup", "delta": 100, "new_rank": 12 }
    ]
  }
}

Sync responses include the rules-engine outcome. Latency: 200 to 800ms typical, depending on how many programs the event triggers.

Retry policy

What to do when ingestion fails

text
Status codes you will see:

  202 Accepted        Async path. Event queued, rules engine will process.
  200 OK              Sync path or duplicate. Body has details.
  400 Bad Request     Schema error. Do NOT retry; fix the payload.
  401 Unauthorized    Bad key. Do NOT retry; fix auth.
  429 Too Many        Rate limited. Retry with Retry-After.
  500/502/503/504     Server error. Retry with exponential backoff.

Retry strategy for 429 and 5xx:
  attempt 1   wait 250ms + jitter
  attempt 2   wait 500ms + jitter
  attempt 3   wait 1000ms + jitter
  attempt 4   wait 2000ms + jitter
  attempt 5+  wait 5000ms + jitter, log a warning

Always include the idempotency_key. Retries are safe.

Common mistakes

What goes wrong on first integration

01Mistake

Sending events without idempotency keys. Network blips double-credit users.

Fix

Always include idempotency_key. Use deterministic format: participant_id : subject : period.

02Mistake

Multiple events to multiple endpoints when one event would do. Wasteful and inconsistent.

Fix

One event per user action. The rules engine fans it out to challenges, contests, and progression. You almost never need to call points and challenges directly.

03Mistake

Using sync everywhere. Higher latency; the user feels it.

Fix

Default to async. Use sync only on screens where the client needs the rules-engine result immediately (a 'congratulations' moment with a live points total).

04Mistake

Batching infrequently used event types. Mixing 50 schemas in one batch makes failures hard to triage.

Fix

Group by event_type when batching. One quiz_completed batch, one purchase_completed batch. Easier to debug.

05Mistake

Ignoring the duplicate flag in the response. Clients re-celebrate the same action.

Fix

Check duplicate. If true, suppress the celebration UI. The points and progress did not change.

Developer FAQ

Common questions when integrating gamification with Bricqs.

Ready to ship?

Wire it up with the Bricqs SDK or API

Headless SDK for React UIs, REST API for any backend. Same engine behind both.

1 brief to align the room2 mechanics max in version one
What happens next
01
Pick the mechanic
Choose the smallest working system for the brief.
02
Launch without rebuilds
Configure rules and rewards in one place.