Skip to content
Guides

Build automatic race entry in 20 lines

Build automatic race entry from thesis events in 20 lines.

The idea behind FomoRun: post a Trade Thesis on $RUN and you're in the next race. No forms, no wallet prompts. FomoData delivers every new thesis to your server as a signed webhook; you check the token and create the entry.

Create a webhook for $RUN theses

In the dashboard, add an endpoint for thesis.created with a token filter of $RUN, or do it with the API. Copy the whsec_… secret into FOMODATA_WEBHOOK_SECRET; it's shown once.

setup.ts
await fomo.webhooks.create({
  url: "https://race.example.com/api/fomodata",
  events: ["thesis.created"],
  filters: { token: ["$RUN"] }
});

Handle the event

This is the whole server, as a Next.js route handler (any Fetch-API runtime works: Hono, Bun, Cloudflare Workers). fomo.webhooks.handle() verifies the FomoData-Signature header against the raw body, rejects stale timestamps and dispatches the event to your on() handlers. If a handler throws it answers 500 and FomoData retries.

import { FomoData } from "@fomodata/sdk";
import { race } from "@/lib/race";

const fomo = new FomoData({
  apiKey: process.env.FOMODATA_API_KEY,
  webhookSecret: process.env.FOMODATA_WEBHOOK_SECRET
});

fomo.webhooks.on("thesis.created", async event => {
  if (event.data.token.symbol !== "$RUN") return;

  await race.createEntry({
    profileId: event.data.profile.id,
    handle: event.data.profile.handle
  });
});

// Verifies FomoData-Signature, dispatches to on(), answers 200 / 400 / 500.
export const POST = (request: Request) => fomo.webhooks.handle(request);

Make entries idempotent

Webhooks are delivered at least once. Key race entries on event.id (or on the thesis id) so a retry or a replay never creates a second entry.

Test it with the sandbox

With a test key and a test-mode webhook, create a sandbox thesis. FomoData emits a labelled thesis.created (livemode: false, source: "sandbox", test: true) and delivers it to your endpoint within seconds.

Terminal
curl -X POST 'https://fomodata.dev/v1/test/theses' \
  -H "Authorization: Bearer $FOMODATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "handle": "@sbx_milo", "token": "$RUN", "text": "Sandbox thesis: testing my race entry flow." }'

Watch the delivery land in Webhooks → Deliveries, with status, response code and latency. Hit Replay to send it again with the same event id and confirm your idempotency.

Go live

Once your project is approved for live access, create the same webhook with a live key. Real $RUN theses now enter real races. Your code doesn't change.

Variations

  • Entry windows. Instead of entering on every thesis, call POST /v1/verify/thesis when a player taps "join", with the race's start and end as the window.
  • Local development. Webhook URLs must be public HTTPS. Locally, use streams instead: fomo.streams.subscribe({ event: "thesis.created", token: "$RUN", onEvent }) runs the same handler without a tunnel.