BricqsBricqs

API: contests

Contests are time-bound competitions with server-side scoring, leaderboard ranking, and prize allocation. The lifecycle (draft, scheduled, active, scoring, completed) is enforced by the API; you do not manage the state machine yourself.

Reading time9 minutes
Last updatedMay 2026

Key takeaways

Quick read
  • Lifecycle: draft → scheduled → active → scoring → completed. Each transition is server-driven.
  • Scoring is event-driven and server-side. Same events that power challenges feed contests when configured.
  • Idempotency is enforced at contest_id : source_fact_id. Duplicate facts never double-score.
  • Prize allocation runs after the window closes. Top-N prizes are auto-assigned and held for verification.
  • Anti-fraud is built in: per-minute and per-hour velocity caps, suspicious rank-jump detection, manual review queue.

Create

Define a contest

POST /api/v1/admin/contests·bash
curl -X POST https://api.bricqs.co/api/v1/admin/contests \
  -H "Authorization: Bearer bq_live_admin_..." \
  -d '{
    "id": "april_quiz_cup",
    "title": "April Quiz Cup",
    "starts_at": "2026-04-01T00:00:00Z",
    "ends_at":   "2026-04-30T23:59:59Z",
    "scoring": {
      "event_type": "quiz_completed",
      "score_attribute": "score",
      "weight": 1
    },
    "prize_structure": [
      { "rank_from": 1, "rank_to": 1,   "reward": { "type": "cash", "value": 50000 } },
      { "rank_from": 2, "rank_to": 5,   "reward": { "type": "cash", "value": 10000 } },
      { "rank_from": 6, "rank_to": 50,  "reward": { "type": "voucher", "value": 500 } }
    ],
    "max_reward_liability": 500000,
    "fraud_rules": {
      "max_score_per_minute": 1000,
      "max_rank_jump_per_hour": 200
    }
  }'

Lifecycle

Five states, server-driven

text
draft
  Created but not yet visible. PATCH freely.

scheduled
  Published. Cannot mutate scoring or prize structure.
  Worker will activate at starts_at.

active
  Window is open. Scoring runs in real time.
  Reads to GET /contests/:id are public-safe (no admin scope).

scoring
  Window has closed. Final score sweep is running.
  Typical duration: under a minute.

completed
  Final ranks frozen. Prizes allocated. Webhook fired.
  Cannot transition back.

Ranking

Read the leaderboard

GET /api/v1/contests/:id/leaderboard·bash
curl "https://api.bricqs.co/api/v1/contests/april_quiz_cup/leaderboard?limit=50" \
  -H "Authorization: Bearer bq_live_..."

# response
{
  "contest_id": "april_quiz_cup",
  "window": "active",
  "as_of": "2026-04-15T12:30:00Z",
  "rows": [
    { "rank": 1, "participant_id": "p_91xx", "display_name": "M.K.", "score": 9450 },
    { "rank": 2, "participant_id": "p_8a3f", "display_name": "You",  "score": 9210 }
  ],
  "total_entries": 12407
}

Bracket

The user's view

bash
GET /api/v1/contests/april_quiz_cup/leaderboard/bracket?around=p_8a3f&size=7

# Returns 7 rows centered on the participant.
# Used by useLeaderboard({ view: "bracket" }) under the hood.

Prize allocation

What happens at completion

text
When the window closes:

  1. Final score sweep runs (under 60 seconds)
  2. Tie-breakers applied (earliest-to-reach, then lifetime score, then random)
  3. Prizes allocated by rank: top winners enter "pending verification"
  4. Verification window: 24 to 72 hours
     - Participant identity, payment method, device fingerprint checked
     - Suspicious entries auto-flagged for manual review
  5. After verification: prize codes issued, webhook fires per winner
  6. Public winners list (configurable consent) published

You do not call any endpoint to trigger this. The lifecycle worker handles it.

Common mistakes

What goes wrong

01Mistake

Changing scoring mid-window. Existing entries get confused; legal review starts.

Fix

Lock scoring before launch. Errata go via a separate erratum contest, not by editing the live one.

02Mistake

Issuing prizes to winners directly. Bypasses the verification window.

Fix

Let the lifecycle worker run. Pending verification is the protection against fraud and disputes.

03Mistake

Polling the leaderboard from every client at 1s. Rate limits hit.

Fix

Use the SDK; it handles polling cadence. Server-side, cache the public leaderboard at 5 to 15 second TTL.

04Mistake

Not capping max_reward_liability. A scoring bug or fraud spike empties the budget.

Fix

Always set max_reward_liability. The lifecycle worker stops allocating prizes once the cap is reached.

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.