HomeCase studiesA Live-Event Prediction and Sponsored-Rewards Mobile Application

Case study · Rotterdam, Netherlands

A Live-Event Prediction and Sponsored-Rewards Mobile Application

Consumer entertainment and audience engagement around scheduled live events, with a sponsorship-funded rewards model

Audiences follow scheduled live events passively, and the sponsors who fund those events have no direct relationship with the people watching. Our team built a mobile application that turns watching into playing: users build a prediction card against a forthcoming event, pick which participant will come out on top at specific measured points within it, and watch those picks resolve automatically as the event unfolds — with sponsor-funded rewards for the top finishers. The engineering centre of the product is not the game; it is the automated ingestion pipeline that pulls schedules, participants, groupings and live measurement data from a syndicated data provider and turns raw telemetry into a scored result, reliably, inside a strict rate limit, while an event is running.

Industry
Consumer entertainment and audience engagement around scheduled live events, with a sponsorship-funded rewards model
Solution
A cross-platform mobile application over a token-authenticated REST API and relational database, with a set of standalone data-ingestion workers integrating a third-party live-event data provider.
Platforms
Cross-platform · Web & API
Stack
React Native · React · Node.js · Express · PostgreSQL · AWS
Location
Rotterdam, Netherlands · delivered remotely
Role
Engineering, with the team behind for mobile and QA

Delivered remotely for a business based in Rotterdam, Netherlands. Names withheld by agreement.

Project Overview

Industry: Consumer entertainment and audience engagement around scheduled live events, with a sponsorship-funded rewards model.

Type of solution: A cross-platform mobile application over a token-authenticated REST API and relational database, with a set of standalone data-ingestion workers integrating a third-party live-event data provider.

Business context: Scheduled live events command large audiences for a few hours and lose them entirely in between. Sponsors underwrite those events without any channel to the audience they are paying to reach. The product's premise is that a lightweight prediction game — free to play, quick to complete, resolved automatically — gives the audience a reason to engage before, during and after an event, and gives sponsors a direct, branded presence in that engagement including the reward itself.

General users: Consumers following the events, playing at no cost. The reward layer is funded by sponsors rather than by the player, and the application contains no payment functionality of any kind.

General purpose: To convert passive audience attention into active, repeatable engagement across an event calendar, and to give sponsors a place inside that engagement.

The Business Challenge

The product is unscoreable without external data. Every element of the game — which events are coming, who is participating, who is grouped with whom, when they start, and what actually happened — originates outside the business. There is no version of this product that works without a reliable integration with a live-event data provider.

That data arrives under a strict quota. The provider enforces a tight per-minute call limit. A full refresh spans many endpoints and many measures, so ingestion has to be paced deliberately rather than run as fast as the network allows. Getting this wrong means either throttling or missing data during the exact window when the data matters most.

Raw measurements are not results. The provider supplies detailed, play-level measurement data. What the product needs is a decision — who was best at this point — and that reduction has to be computed. It also has to be right, because it determines who receives a reward.

The pick window is short and externally imposed. Picks must be final before a segment begins, and the information the user needs to make them is published by the provider only shortly beforehand. The product has no control over that timing, which means the pick flow has to become available the moment upstream data lands and close cleanly when the segment starts.

Too much choice makes a worse game. Presenting the entire field of participants would be both overwhelming and dull. The product has to curate what it offers, automatically and consistently, without an editor making the call before every event.

A card's state changes without anyone touching it. A prediction card moves from selected, to ready, to in progress, to played purely because time passes. Modelling that as stored state means something has to sweep the table and keep it accurate — and be right about it, in every timezone, for every event.

Rewards are physical. The user's payoff is not points or credit; it is a product that has to be claimed and shipped. That is a fulfilment flow, not a balance.

And it had to exist by a date nobody controlled. The product is only meaningful during a live event calendar. There was no option to ship late and catch up.

Our Approach

Take ingestion off the request path completely. Rather than calling the data provider inside request handlers, we built dedicated ingestion workers with different cadences: a one-off backfill for the catalogue, a daily refresh for participant statistics, a pre-event worker that builds the groups and the eligible outcome points, and a live worker that runs during an event. They write to the database directly and share nothing with the API process. The user-facing API therefore never blocks on a third party, and a provider outage degrades data freshness instead of taking the product down.

Make every worker safe to re-run. Each worker checks whether a record already exists before inserting it, and the live worker rewrites a segment's data wholesale rather than attempting to reconcile differences. When a provider call fails halfway through — which, with a third-party feed during a live event, it will — the operator's response is simply to run it again. No cleanup, no duplicate rows, no partial state to reason about. This is a small design decision that removes an entire category of incident.

Build the rate limit into the pipeline rather than around it. Pacing between provider calls is part of how the workers are written, not an afterthought applied when throttling appears. A full statistics refresh takes minutes by design, and that is the correct trade: it runs off the request path, so nothing user-facing is waiting for it.

Reduce telemetry to a result inside the pipeline. The worker that ingests measurement data also performs the reduction — grouping measurements by outcome point and identifying the best one — so the API and the client both read a settled result rather than each deriving their own. There is exactly one place in the system where an outcome is decided.

Curate automatically. Which participant groups a user is offered is determined by the system, weighted by an independent ranking, so every user gets a consistently interesting set of choices without anyone curating an event by hand.

Derive card status instead of storing it. A card's lifecycle state is computed from the event calendar at the moment it is queried. Nothing has to advance it, nothing can be missed, and status cannot drift out of step with reality.

Use the right data access tool for each job. An object-relational mapper handles identity, roles and their relationships, where the mapping is genuinely useful. Parameterised SQL handles the composite read paths, where assembling an event, its venue, its segments, its participants and the user's existing picks in one response is far clearer written directly — and results in one round trip instead of several for a client on mobile connectivity.

Make the client's async flow explicit. All asynchronous work in the mobile application runs through a saga layer, so multi-step flows — create a card then refresh the list, verify a code then navigate, reset then sign out — are each written as a single readable sequence rather than as chained callbacks inside components.

Design once, scale everywhere. A single scaling system converts design units to device units across every screen, so the application renders consistently from small phones to tablets without per-screen breakpoint work.

The Solution

Event calendar and discovery. Users browse forthcoming events by date range and select one to play, with venue and scheduling detail attached.

Prediction card creation. A card is created against a chosen event and a chosen segment within it. A user can hold several cards across the calendar, and remove one with a swipe.

Automatic card lifecycle. Each card presents itself as selected, ready to play, in progress or played, derived from the event calendar, with the appropriate action surfaced for its state.

Pick-window countdown. A visual countdown to the moment picks lock, so the user knows exactly how long they have.

Guided pick flow. For each eligible outcome point in the segment, the application presents the participants in the curated groups, with profile access, and records the user's selection before advancing.

Participant directory and profiles. An alphabetical directory of participants, each with a profile showing performance statistics across multiple measures alongside an independent ranking.

Automatic outcome resolution. Picks are resolved from the provider's detailed measurement data ingested during the event, with no manual scoring and no user action required.

Live progress and summaries. Card summaries for cards in progress and cards completed, showing how each pick fared.

Tie-breaker. An estimate-based tie-breaker captured at submission, so close finishes resolve cleanly.

Rankings. Per-event rankings against other players, and an overall view across the calendar.

Reward claim. Winners reach a confirmation flow, view the sponsor-funded reward, and provide shipping details to claim it.

Sponsor showcase. A browsable sponsor section with individual sponsor detail, and a gallery for the reward item — giving sponsors presence inside the engagement they fund.

Account and recovery. Registration, sign-in, email-based account recovery with a verification code, and credential change from within the application, with sessions persisted so returning users open straight into their cards.

Key Features

Automated multi-cadence data ingestion Four purpose-built ingestion workers — catalogue backfill, daily statistics refresh, pre-event preparation and live in-event updates — each running at the cadence its data actually changes, entirely off the user-facing request path.

Idempotent-by-construction pipeline Every worker verifies before it writes, so any run can be repeated safely after a partial failure. Recovery from a third-party outage is re-running the job, not repairing data.

Rate-limit-aware provider integration Pacing between calls is designed into the pipeline, so a large refresh across many endpoints completes within the provider's quota rather than being throttled at the worst possible moment.

Automatic outcome resolution from live measurement data Detailed measurement data is reduced to a settled result in one place in the system, so scoring is automatic, consistent and identical for every consumer of it.

Curated participant selection The system determines which groups a user is offered, weighted by an independent ranking, giving every user a consistently compelling set of choices without manual curation per event.

Calendar-derived card lifecycle Card status is computed from event timing at query time rather than stored, so it cannot fall out of sync and requires no background process to maintain.

Guided, time-boxed prediction flow A stepped pick flow with a visual countdown to the lock, profile access at the point of decision, and a tie-breaker at submission.

Rankings and automatic scoring Per-event and overall rankings, populated from resolved outcomes with no manual intervention.

Sponsor-funded reward fulfilment A complete winner journey from confirmation through reward presentation to a shipping claim — a physical fulfilment flow, with no payment functionality anywhere in the product.

Integrated sponsor presence A sponsor showcase and reward gallery built into the primary navigation, giving the funding partners a genuine place in the user experience rather than a banner.

Technical Architecture

Mobile client. A cross-platform application built around a central store with a saga layer owning all asynchronous work. Navigation combines stack navigators with a drawer and a custom sidebar; state is split into authentication, event and participant slices, with the session persisted on device and rehydrated at launch. A single design-scale system drives layout across device sizes. Animation is used deliberately at the emotional beats of the game — calculating, winning, tie-breaking — with a circular countdown driving the pick window.

API layer. A stateless REST service with bearer-token authentication and role-checking middleware, organised into route modules by resource — events, participants, cards and authentication — over thin controllers. Read endpoints return composite responses assembled server-side, so a client on mobile connectivity retrieves an event, its venue, its segments, its participants and its own pick state in a single call.

Data access. Two deliberate styles over one relational schema: an object-relational mapper for identity, roles and their join relationships, where the mapping earns its place; and parameterised SQL for the composite read paths, where the queries are clearer written directly and the round-trip saving is significant.

Ingestion layer. Four standalone workers with independent cadences, integrating a syndicated live-event data provider across its schedule, catalogue, participant, grouping, scoreboard and measurement endpoints. Each performs existence checks before writing, paces itself against the provider's quota, and catches and reports failures per record rather than aborting a run. The live worker also performs the reduction from raw measurement data to a resolved outcome.

Data layer. A managed cloud relational database holding the event catalogue, venues and segments, participants and their statistics, groupings, cards, picks, resolved outcomes and rankings, with referential integrity enforced throughout.

Supporting services. Transactional email for account recovery, and cloud-hosted database infrastructure.

Flow: Mobile app → Saga layer → Token-authenticated REST API → Composite SQL reads → Relational database ← Independent ingestion workers ← Syndicated live-event data provider

Technology Stack

Category Technology
Backend runtime Node.js
Backend framework Express with promise-based routing
Database PostgreSQL, managed cloud instance (AWS RDS)
Data access Sequelize ORM for identity and relationships; pooled parameterised SQL for composite reads
API authentication JSON Web Token bearer authentication with role-checking middleware
Credential storage bcrypt hashing
Outbound integration Axios against a syndicated live-event data provider
Transactional email Nodemailer over hosted SMTP
Configuration Environment-based configuration for the service tier
Ingestion Standalone Node workers with existence checks and quota-aware pacing
Mobile framework React Native under Expo
Mobile navigation React Navigation — stack navigators with a drawer and custom sidebar
Mobile state Redux with Redux-Saga for asynchronous orchestration
Mobile networking Axios with a request interceptor for base-URL resolution
Mobile persistence Device key-value storage for session and user context
Mobile UI React Native Paper, SVG rendering, Lottie animation, progress and countdown components
Mobile input Date-range selection, confirmation code entry, swipe-to-delete lists, pager and swiper views
Mobile layout Custom design-unit scaling system applied across all screens

Technical Challenges & Solutions

Challenge Our Approach
The entire product depends on one external data provider for schedules, participants, groupings and live results Ingestion was isolated into standalone workers that never run inside a request. The user-facing API reads only from our own database, so provider latency or an outage degrades data freshness rather than availability, and the failure is recoverable by re-running a job.
A strict per-minute quota on provider calls, against a refresh spanning many endpoints and measures Quota-aware pacing was designed into the workers rather than bolted on. A full refresh takes minutes deliberately — acceptable precisely because it runs off the request path, where nothing user-facing is waiting on it.
Third-party feeds fail partway through, especially during a live event Every worker checks for existence before inserting, and the live worker rewrites a segment's data wholesale rather than reconciling. Any run is safe to repeat, so recovery is re-running the job — no cleanup, no duplicates, no partial state.
Detailed measurement data is not a result, and the result decides who wins a reward The reduction from raw measurements to a resolved outcome happens once, inside the ingestion worker, so every consumer reads the same settled result rather than deriving its own. One place in the system decides an outcome.
Presenting the full field of participants would make the game both overwhelming and dull The system selects which groups a user is offered, weighted by an independent ranking, so curation is automatic and consistent across every event without an editor preparing each one.
Card status changes purely because time passes, across four states Status is computed from the event calendar at query time rather than stored. Nothing has to advance it, nothing can be missed, and it cannot drift out of step with the calendar.
A mobile client on variable connectivity needing rich, related data per screen Composite responses assembled server-side — event, venue, segments, participants and the user's own pick state in a single call — so a screen renders from one round trip rather than several.
Multi-step asynchronous flows in the client becoming tangled All asynchronous work runs through a saga layer, so each flow is written as one readable sequence with its error handling and navigation in the same place.
One codebase rendering consistently across phone and tablet sizes A single design-unit scaling system used by every screen, so layout scales proportionally without per-screen breakpoint work.

Security & Reliability

Token-based authentication. Every substantive endpoint requires a bearer token, issued at sign-in and verified by middleware before a request reaches a controller.

Hashed credentials. User credentials are stored only as salted hashes and are never returned by an authentication response.

Role model. A defined role structure with guard middleware, giving the platform a place to attach elevated capability as it grows.

Parameterised queries throughout the service tier. Every user-supplied value in the request-serving code is bound as a parameter rather than concatenated, and path parameters are coerced to their expected types before use.

Recoverable, repeatable ingestion. Because every worker verifies before writing, a failed run has no partial-state consequences. This is a reliability property as much as a correctness one: the operational response to a provider failure during a live event is to run the job again, which is the response most likely to be correct under time pressure.

Defensive failure handling in the pipeline. Provider calls are wrapped so that a failure on one record or one endpoint is caught and reported rather than aborting an entire ingestion run.

A single source of truth for outcomes. Because outcome resolution happens in exactly one place in the system, there is no possibility of the client, the API and the rankings disagreeing about who won.

Referential integrity. The schema enforces relationships between events, venues, participants, groupings, cards, picks and outcomes at the database level.

Stateless service tier. Session state lives in the token and persistent state in the database, so application instances hold nothing locally.

No payment surface. The product handles no payment credentials, no stored value and no monetary balances. Rewards are physical items fulfilled by shipping, which removes an entire class of risk from the product's scope.

Scalability & Performance

Ingestion isolated from the request path. The heaviest and least predictable work in the system — talking to a third party, at volume, under a quota — never touches a user request. This is the single most important scalability property of the architecture, and it was a design decision rather than an optimisation.

Stateless, horizontally replicable service tier. Token authentication and externalised state mean application instances can be added without coordination.

Pooled database connections. Connection pooling in the service tier keeps connection establishment off the per-request path.

Composite responses over chatty ones. Assembling related data server-side reduces round trips for clients on mobile networks, where latency rather than bandwidth is the constraint.

Cadence matched to volatility. Catalogue data is loaded once, statistics refresh daily, groupings load before an event and only live data updates during one. Nothing is fetched more often than it changes.

Client-side state caching. The mobile client holds fetched data in its store and refetches on screen focus rather than on every render, keeping network usage proportional to user activity.

Bundled visual assets. Interface imagery and animation ship with the application rather than being fetched, so screens render immediately regardless of connectivity.

Managed database infrastructure. Running on managed cloud database infrastructure provides a straightforward vertical scaling path and takes backup and availability management off the delivery team.

Business Outcomes

  • A passive audience gained something to do. Events that were previously watched became events that could be played, with a reason to open the application before, during and after.
  • Engagement extends across the calendar, not just the event. Card creation happens days ahead, picks happen in a defined window, results resolve live, and rankings persist afterwards — four separate reasons to return.
  • Scoring runs without human intervention. Outcomes resolve automatically from ingested measurement data, so the product does not require an operator watching an event to score it.
  • Data freshness survives provider problems. Because ingestion is isolated and every job is safe to repeat, a third-party failure during a live event is a recoverable data-freshness issue rather than an outage.
  • Sponsors gained a direct channel to the audience. Sponsor presence is built into the navigation and into the reward itself, rather than being a banner alongside unrelated content.
  • The product carries no payment risk. With rewards fulfilled physically and no payment functionality, the product avoids the compliance and security surface that a transactional model would have required.
  • A complete product reached users inside a live event calendar. Both tiers — application and service — were delivered against an immovable external deadline set by the events themselves.

Why it worked

Products built around live events have an unusual failure mode: they are not judged when they are convenient to judge. They are judged during the event, when the third-party feed is under load, when the data arrives late, and when every user is looking at the same screen at the same moment. Most of the engineering that matters in a product like this is invisible when it works.

That is where we put the effort. We took the entire third-party dependency off the user-facing path, so the thing most likely to fail cannot take the product down with it. We made every ingestion job safe to repeat, because the correct response to a failure at 3pm during a live event has to be simple enough to get right under pressure. We built the provider's rate limit into the design of the pipeline rather than discovering it in production. And we made outcome resolution happen in exactly one place, because a prediction game that disagrees with itself about who won has no product left.

We also made the judgement calls a small product needs. Status derived from the calendar rather than stored and swept. An object-relational mapper where mapping helps and direct SQL where it does not. Composite responses because the client is on a mobile network. Curation done by the system so the game stays interesting without an editor preparing each event.

Our teams work across Node.js service development, relational data modelling, third-party data integration under real-world constraints, ingestion pipeline design, and cross-platform mobile application development — with the judgement to know which parts of a system deserve careful engineering and which parts simply need to work by a date that is not negotiable.

Final Summary

A live event holds an audience for a few hours and loses it completely in between, while the sponsors funding it have no way to reach the people they are paying to reach. This product closes both gaps with a prediction game: build a card against a forthcoming event, pick which participants will come out on top at specific measured points within it, watch those picks resolve as the event runs, and — for the top finishers — claim a sponsor-funded reward.

The visible product is a cross-platform mobile application: an event calendar, a card lifecycle that advances itself, a countdown to the pick lock, a guided pick flow with participant profiles at the point of decision, a tie-breaker, rankings, and a reward claim that ends in a shipping form. Behind it is a token-authenticated service returning composite responses built for mobile connectivity, over a relational schema that models events, venues, participants, groupings, cards, picks and outcomes with integrity enforced at the database.

The engineering that decides whether the product works, though, is the ingestion layer. Four independent workers pull schedules, catalogue data, participant statistics, groupings and live measurements from a syndicated data provider at four different cadences, entirely off the request path. Every one of them checks before it writes, so any job can be re-run safely after the partial failures a live third-party feed inevitably produces. Every one of them paces itself to stay inside the provider's quota. And one of them performs the reduction from raw measurement data to a resolved outcome — once, in one place, so that the application, the rankings and the reward all agree about who won. That is the part nobody sees, and it is the part the product stands on.

01 — Questions

asked about this kind of project

How do you build an application that depends entirely on a third-party data feed?

By making sure the feed is never in the user's path. Ingestion runs as separate workers that write to your own database, and the application reads only from that. The provider can be slow, throttled or down, and the worst outcome is data that is a few minutes stale rather than an application that will not load. If provider calls happen inside request handlers, you have simply outsourced your uptime to someone else's infrastructure.

What makes a data ingestion pipeline reliable?

Being safe to re-run. Third-party feeds fail partway through — that is a normal operating condition, not an exception. If every job checks whether a record already exists before writing it, then the recovery procedure for any failure is to run the job again. No cleanup, no duplicate records, no partial state to reason about. It is a small amount of extra code that removes an entire category of incident, and it matters most at exactly the moment you have least time to think.

How do you handle third-party API rate limits?

Design for the limit rather than reacting to it. Pacing between calls belongs in the structure of the pipeline from the start, sized to the quota you actually have. This makes large refreshes slow, which is acceptable precisely because they run off the request path — nothing user-facing is waiting on them. The alternative, discovering the limit in production during a live event, is the worst possible time to find out.

Should derived state be stored or computed?

Compute it when it is a pure function of data you already hold. A status that changes only because time has passed does not need a stored column and a background job to advance it — it needs a calculation at read time. Stored derived state introduces a class of bug that is hard to detect and embarrassing when found: the record says one thing, reality says another, and nobody knows how long it has been wrong.

When should you use an ORM and when should you write SQL?

Both, in the same application, for different jobs. Object-relational mapping is genuinely useful for identity, relationships and the ordinary create-and-fetch work around them. Composite read paths that join several tables and shape a response for a specific screen are usually clearer written as SQL, and the performance is easier to reason about. The rule that matters more than either choice: whichever you use, bind your parameters.

Why does a mobile client need composite API responses?

Because on a mobile network the cost is latency, not bandwidth. Five small requests are meaningfully slower than one larger one, and the difference is visible to the user as a screen that assembles itself in stages. Shaping responses around what a screen needs, rather than around what is tidy from a resource-modelling perspective, is one of the highest-value decisions in a mobile-first API.

How do you deliver a product against an immovable external deadline?

Decide early which parts must be right and which parts only need to work. In a product like this, the ingestion and scoring path must be right — it decides who wins — so it gets careful design, idempotency and a single source of truth for outcomes. Presentation, animation and secondary screens can be built pragmatically and improved afterwards. Attempting uniform quality across everything is how a fixed-date product misses its date.

What should be built first in a data-dependent product?

The pipeline. Every feature you can demo depends on the data being there, correct and current, and integration with a third-party provider always takes longer than the estimate — quotas, sandbox and production differences, undocumented response shapes, intermittent failures. Building the interface first produces something that looks finished and does nothing. Building the pipeline first produces something that looks like nothing and is actually most of the product.

03 — Similar project?

describe what is different about yours

Build yours.

Tell me what exists, what you need and the deadline. Fixed price for a defined scope, or hourly from $10 with a written estimate first.

Ahmedabad, India · IST (UTC+5:30) · --:-- IST · Mon–Fri 09:00–18:00 IST · US & EU overlap daily

No newsletter, no CRM. Just a reply.