Hackathon · Unicorn Mafia × Techbible Hack Night · London 2026

WILDSCAN

Protected wildlife is listed openly online, in words a simple search misses.

A tool that screens online marketplace listings for wildlife trafficking and gives each one a risk score investigators can trace point by point.

Event
Unicorn Mafia × Techbible Hack Night, London
Result
Overall Winner
Stack
Python, LangGraph, PostGIS, Next.js, GPT-4o, Claude
Team
Joan Torres Gordo
WILDSCAN landing page for its multi-agent wildlife trafficking detection network

Why it matters

Elephant ivory and tiger parts are protected by CITES, the treaty that controls the international wildlife trade, yet listings for them still turn up on ordinary online marketplaces. When we searched Facebook Marketplace in Thailand for ivory, tiger fang and turtle shell, in Thai and English, it returned 98 listings, one of them titled, in Thai, "genuine ivory". The listings are written in local languages and the words that matter are not always the obvious ones, so reading them one by one does not scale. WILDSCAN reads each listing and its photos, checks the species against the treaty and past seizures, and shows where every point of its score came from.

How it works

Bright Data

Fetches the marketplace pages

Web MCP · scrape_as_html

Triage

Keeps code words and risky categories

string match · no model

  • word list checked
  • category checked

Linguist

Translates it and finds code words

GPT-4o · Claude when unsure

  • translated
  • code word matched

"Genuine ivory"

Image analyst

Looks for wildlife products in the photos

GPT-4o Vision · up to 3 photos

Two tusks on stands

Species check

Looks up the treaty and past seizures

53 species · 80 seizures

  • species matched
  • words and photo agree

Legal trade: no

Risk score

Adds up the points

no model · red from 80

81 RED ALERT

Intel brief

For red and amber alerts

Claude Sonnet · with chat

  • summary
  • evidence
  • recommended actions
ListingWordsPhotoRiskSolid boxes are what we built. Dashed ones are outside services.

Decisions we made

  1. Protection status from our own tables

    The CITES appendix, the IUCN status and the seizure history all come from tables we built: 53 species, with their IUCN status checked against the Red List, and 80 seizures, each linked to its source. The species check is a database lookup, so whether a species is protected never depends on what a model remembers.

    Trade-off. The tables are a snapshot. A species outside our 53 scores nothing for the treaty, however clearly the listing names it.

  2. A word list first, Claude only when unsure

    Each listing is matched against a list of code words: exact words, disguised spellings and near matches, with words that cancel a match, such as museum next to ivory, and words that must appear alongside it. Claude is asked only when the best match is uncertain, or when a listing in a risky category matches nothing. GPT-4o translates every listing for the investigator.

    Trade-off. A list only knows the words someone wrote down. Ours has about a hundred, in five languages, so a seller using a new word is caught only if Claude spots it or the photo gives it away.

  3. Every point can be traced

    The score is plain arithmetic: points for the code word, the CITES appendix, the IUCN status, past seizures, the place and the photo, plus five when the words and the photo point to the same species. For the "genuine ivory" listing, GPT-4o saw two tusks on stands: 12 points for the photo and 5 for agreeing with the words, for 81 in total, a red alert. The investigator sees each signal as its own bar.

    Trade-off. The weights are our own judgement. With no labelled listings to test them on, we cannot say how many of the alerts are right.

Gallery

The WILDSCAN command centre after a scan of Thailand, with scored listings pinned across a map of Southeast Asia
The WILDSCAN command centre before a scan, with a map of Southeast Asia and a Scan Thailand button
A Thai listing titled genuine ivory, open beside the map with a score of 81, a red alert, and a bar for each signal behind it

The full engineering is on GitHub.