HackathonRadar
Get an API key
Integrations and AIWebhooks

Integrations and AI

Webhooks

Get an HTTP POST on your own server when hackathons are added or updated, with the payload shape and how to secure it

Webhooks send hackathon data to a URL you control when HackathonRadar adds or changes an event. You manage them at /settings/webhooks.

Create an endpoint

  1. Open Webhooks

  2. Enter your URL

    Paste the address that should receive deliveries, for example https://example.com/webhook. Use https.
  3. Pick a delivery type

    Choose All Updates or Newly Seen from the dropdown. The next section explains the difference.
  4. Add headers (optional)

    Click Add Header to send fixed headers with every delivery, such as a shared secret. Add as many as you need.
  5. Create it

    Click Create Webhook. The endpoint appears in the list as Active.

Each endpoint in the list shows its URL, type, status, when it was created and when it Last fired. Use the switch to pause or resume it, and the trash button to delete it. You can create several endpoints.

What gets delivered and when

Delivery typeWhat you receiveevent_type
Newly SeenEach hackathon when it is first added to HackathonRadarcreated
All UpdatesEach hackathon when it is added or changes, including when it is removed or restoredupdated

Deliveries go out as changes happen, and a daily run sends anything since your endpoint last fired. A new endpoint gets the last 24 hours of hackathons in its first daily run.

Some things to plan for:

  • One hackathon per request. Each POST carries a single hackathon.
  • Upsert on id. The same hackathon can arrive more than once, for example when it changes twice in a day. Store deliveries keyed on id rather than inserting a new row each time.
  • All Updates includes new hackathons, labelled updated. Compare first_seen_at with last_seen_at if you need to tell them apart.
  • Removed hackathons arrive with is_deleted: true.
  • Every hackathon is sent. Webhooks cannot be limited to a saved search, so filter on your side.

Payload

Every delivery is a POST with Content-Type: application/json. The body is the full hackathon record, plus event_type, timestamp, organizers, sponsors and quality_score. This example is shortened.

POST body
{
  "id": "7f1c2a9e-3b4d-4e5f-8a6b-9c0d1e2f3a4b",
  "event_type": "created",
  "timestamp": "2026-10-24T08:14:03.512Z",
  "title": "Bristol AI Build Weekend",
  "slug": "bristol-ai-build-weekend",
  "start_at": "2026-11-14T09:00:00.000Z",
  "end_at": "2026-11-15T18:00:00.000Z",
  "timezone": "Europe/London",
  "type": "in-person",
  "categories": ["AI", "Open Source"],
  "prize_pool": 5000,
  "prize_currency": "GBP",
  "prize_pool_usd": 6300,
  "cash_prizes": true,
  "venue_name": "Engine Shed",
  "city": "Bristol",
  "country": "United Kingdom",
  "lat": 51.449,
  "lng": -2.581,
  "website_url": "https://example.com/bristol-ai",
  "registration_url": "https://example.com/bristol-ai/register",
  "student_only": false,
  "participant_count": 120,
  "description": "A weekend of building with AI...",
  "first_seen_at": "2026-10-24T08:13:58.000Z",
  "last_seen_at": "2026-10-24T08:13:58.000Z",
  "enriched": true,
  "featured": false,
  "is_deleted": false,
  "organizers": [
    {
      "id": "b2c3d4e5-0000-4000-8000-000000000001",
      "name": "Bristol Builders",
      "domain": "bristolbuilders.example",
      "website_url": "https://bristolbuilders.example",
      "twitter": null,
      "linkedin": null,
      "instagram": null,
      "image_url": null,
      "email": "hello@bristolbuilders.example",
      "email_confidence": 0.9,
      "created_at": "2026-03-02T10:00:00.000Z"
    }
  ],
  "sponsors": [
    {
      "id": "c3d4e5f6-0000-4000-8000-000000000002",
      "name": "Example Cloud",
      "domain": "examplecloud.example",
      "website_url": "https://examplecloud.example",
      "logo_url": "https://example.com/logos/example-cloud.png",
      "sponsored_count": 14
    }
  ],
  "quality_score": {
    "score_total": 78,
    "confidence": 0.85,
    "reasons_json": ["Clear prize information", "Named sponsors"],
    "computed_at": "2026-10-24T08:20:00.000Z"
  }
}

quality_score is null until a score has been computed, and organizers and sponsors are empty arrays when none are known. Field meanings match the REST API.

Secure your endpoint

To make sure a request came from HackathonRadar, add a secret header when you create the endpoint and reject requests without it.

  1. Make a secret

    Generate a long random value, for example with openssl rand -hex 32.
  2. Add it as a header

    On /settings/webhooks, click Add Header. Use a name such as X-Webhook-Secret and paste the value.
  3. Check it on your server

    Compare the header with your stored value before you trust the body.
Node.js (Express)
import crypto from "node:crypto";
 
app.post("/webhook", express.json({ limit: "2mb" }), (req, res) => {
  const got = Buffer.from(req.get("X-Webhook-Secret") ?? "");
  const want = Buffer.from(process.env.RADAR_WEBHOOK_SECRET);
  if (got.length !== want.length || !crypto.timingSafeEqual(got, want)) {
    return res.sendStatus(401);
  }
  res.sendStatus(200); // reply first, then process
  upsertHackathon(req.body); // keyed on req.body.id
});

Headers are stored with the endpoint and cannot be edited. To rotate a secret, create a new endpoint with the new header, then delete the old one.

When a delivery fails

Any 2xx response counts as delivered. A failed delivery (an error status or an unreachable server) is not resent, so a hackathon you missed arrives again only if it changes. Reply quickly and do heavy work after responding.

If your endpoint was down, backfill the gap with the REST API. To stop deliveries while you fix something, turn the endpoint's switch off. Turning it back on resumes from its last delivery.

Test an endpoint

There is no test button. To see real deliveries before you build a receiver, create an endpoint pointing at a request inspector you control, choose All Updates, and wait for the next change or the daily run. Delete the test endpoint when you are done.