TLTan LeBackend & automation · CalgaryLet’s talk
← All posts

Building a Market-Intelligence Platform for a Ticket Broker (Freelance Project)

A year of freelance work for a US ticket broker: Ticketmaster event ingest, seat-availability snapshots as time series, Slack alerts, and data pipelines running across two clouds.

Before my current automation work, I spent about a year as a freelancer building a market-intelligence and purchasing-workflow platform for a US ticket-brokerage client. The secondary ticket market moves fast: events go on sale at a fixed minute, prices and seat availability shift constantly across a dozen marketplaces, and the brokers who win are the ones who see changes first. My job was to give a small operations team that visibility — and to automate as much of the surrounding workflow as possible.

This post is a technical retrospective of that system: what it did, how it was architected, and what I learned running data pipelines across two clouds.

What the platform did

At its core, the system ran four loops for the operations team:

  • Primary-market ingest. Scheduled jobs pulled upcoming events from Ticketmaster’s APIs — by state, by venue, by on-sale date — into a local SQL Server database, so the team planned their week from one screen instead of a dozen browser tabs.
  • Availability monitoring. The system took recurring snapshots of seat availability per event and per section, and the Angular front end rendered them as time-series charts (ApexCharts). Watching a section’s inventory curve over hours tells a broker far more than a single point-in-time look.
  • Real-time alerting. Operators configured section-level and ticket-count alerts. When thresholds were hit, the system pushed formatted alert tables into Slack — each row carrying a pre-built deep link to the exact listing checkout, so an operator went from alert to purchase page in one click. This was the operationally hottest feature: during an on-sale, seconds matter.
  • Secondary-market price tracking. Parallel monitors followed listings and lowest-price movement on resale marketplaces (StubHub, TickPick and others), with keyword filters to cut noise, feeding the same charting and alerting machinery.

Around those loops sat supporting workflow tools: capturing checkout sessions and queue positions so multiple operators could coordinate during high-demand on-sales, and back-office sync of invoices and purchase orders with SkyBox, the ERP most ticket brokers run on.

Architecture

The solution grew into a fairly complete distributed system:

  • ASP.NET Core Web API (.NET 7) — the central REST API: authentication (JWT with refresh tokens and custom middleware), event and monitoring endpoints, reporting. EF Core for standard access, with Dapper and stored procedures on the hot query paths. Serilog for structured logging. Deployed to AWS Elastic Beanstalk, backed by SQL Server on AWS RDS.
  • Angular 13 SPA — the operator console (ng-zorro-antd, ApexCharts): dashboards, monitoring screens, alert configuration, analytics charts, user management. Served from the API’s wwwroot, with a JWT interceptor and route guards.
  • Azure Functions (.NET 6/7) — the background tier: timer-triggered ingest jobs (event downloads, on-sale scans, seat maps), HTTP-triggered data-entry endpoints receiving marketplace data, cross-marketplace event matching (e.g. reconciling the same event across Ticketmaster and VividSeats), and webhook-driven SkyBox invoice/PO synchronization. Heavy transformations were pushed down into SQL stored procedures rather than done in C#.
  • Chrome extension — a data-capture companion for the operators. As they browsed the marketplaces they already worked in daily, a content script captured the inventory and pricing payloads those pages loaded and forwarded them to the ingest endpoints. This turned the team’s normal browsing into a live data feed across ten-plus sites that publish no official APIs, without a separate scraping fleet to maintain.
  • Slack as the alert delivery channel — no custom notification UI to build, mobile push for free, and a natural shared feed the whole team saw at once.

Under the shared libraries sat an in-house data-access SDK I maintained — generic query/service abstractions, unit-of-work, bulk operations and paging — reused across projects rather than rewritten each time.

What I learned

  • Latency is a product feature. For most CRUD apps, a second here or there is invisible. In this domain, the entire value proposition was “see it before everyone else.” That justified choices I’d normally avoid — stored procedures on hot paths, pre-built deep links in alerts, pushing data through Slack instead of a polished in-app inbox — because every hop removed was measurable value to the client.
  • Two clouds is twice the operational surface. The API lived on AWS (Beanstalk + RDS) while the background jobs lived on Azure (Functions, Azure SQL, App Insights). Each side was chosen for sensible local reasons, but the split cost real effort in credentials, monitoring, and deployment routines. Today I’d consolidate early — or at least draw the boundary along a clean seam, not wherever history left it.
  • Browser-side capture beats server-side scraping for resilience. Marketplace sites change their markup constantly and defend against datacenter traffic. Capturing the structured JSON the site itself loads, inside a real operator’s session, proved dramatically more stable than parsing HTML from a server farm — and it piggybacked on work the operators were doing anyway.
  • Freelancing means owning the whole lifecycle. There was no separate DevOps or DBA. I designed the schema, wrote the API and the SPA, built the functions, deployed to both clouds, and answered the Slack message when a chart looked wrong. That end-to-end ownership is the single biggest thing the engagement taught me, and it’s shaped how I scope and de-risk every system I’ve built since.

More case studies in Systems in daily production, or reach me at [email protected].

First published on tanldt.blogspot.com on Aug 31, 2026.