How a referral link grew into CrowdRelay

I wanted a useful backend for independent artists. A smart link grew into campaigns, rewards, concerts, tickets and QR check-ins.

Updated 3 min read

CrowdRelay started from a practical idea: independent artists should be able to collect their own fan data, see where people actually want a concert, and reward the fans who help spread the word. No mysterious advertising dashboard, no platform owning the relationship, no ten disconnected tools held together by exports and hope.

How the scope grew

The first flow was simple enough: a smart link, a registration form and a referral code. Then came double opt-in, consent, unsubscribe, city demand, concert interest, reminders, deterministic rewards, weighted draws, admission passes and QR check-ins. At some point I had to admit I was no longer building a clever form for Virya. I was building a small event and community backend.

Keeping the public request simple

The public request stays boring. A person registers and gets a response. The API doesn't wait for an email provider, Discord, Bandsintown or any other service. External deliveries go through a transactional outbox, and workers pick them up later. If a provider is down, the registration still exists and the work is still visible.

Where state lives

The Virya website is only the presentation layer. It can show the counter, the next reward, a concert campaign or a ticket in somebody's wallet, but it doesn't decide whether any of those things are real. CrowdRelay and PostgreSQL own that state. Staff operations use separate permissions, signed webhooks have replay protection, and a QR check-in is an atomic operation, because the entrance to a concert is a terrible place to discover a race condition. :)

Why Rust

Fan forms don't need absurd throughput. I chose Rust because this project is full of explicit states, background work, retries and operations that must happen once even when the network makes it look like they happened zero or two times. Rust makes those transitions easier to see, while PostgreSQL does the durability work through transactions and constraints.

What it covers now

The project now covers campaigns, smart links, fan accounts, referrals, city demand, concert interest, reminders, ticket sales, admission passes, QR check-ins, weighted draws, a reward ledger, signed event delivery and an operational control plane. Deterministic draw receipts can also be committed to Rekor through an isolated proof anchor, while PostgreSQL remains the source of truth.

One backend, several frontends

Virya Signal uses the same backend from a mobile shell, and the Virya website consumes it without receiving operator credentials. That was another useful milestone: CrowdRelay stopped being “the backend behind one form” and became infrastructure shared by several independent surfaces.

There's still plenty I want to add, but it already solves a problem I know well from running a band. The data exists, the fans exist and the ideas exist; what's usually missing is one coherent system between them.

A small note: the CrowdRelay repositories are now private. The project grew far beyond what I expected when I first wrote about it, and at some point the codebase held enough operational detail and tenant-specific logic that keeping it public stopped making sense. I'm still happy to talk about the architecture, the decisions and the trade-offs, so if you're curious about anything here, just reach out.

You can see my other work on GitHub.

Loading…