DEV Community

Cover image for Building a Trade Show Ticketing Pipeline with Open Data and pretix
Ivan Xu
Ivan Xu

Posted on

Building a Trade Show Ticketing Pipeline with Open Data and pretix

Building a Trade Show Ticketing Pipeline with Open Data and pretix

The trade show industry generates over $30 billion annually. Yet finding basic, structured data about trade shows — names, dates, venues, industries — is surprisingly difficult. Most information is scattered across hundreds of event websites, many outdated, and none machine-readable.

Meanwhile, if you're using pretix (the open-source event ticketing platform) to manage trade show registrations, you're manually entering every event's details from scratch.

In this tutorial, I'll show you how to connect an open trade show dataset to pretix's REST API — so you can spin up ticketing for any major trade show in seconds instead of minutes.

The Problem

Imagine you organize ticketing for multiple trade shows per year. For each one, you need to:

  1. Look up the show's official dates and venue
  2. Create the event in pretix
  3. Set up ticket types (exhibitor, visitor, VIP, press)
  4. Configure the right currency and timezone

That's 15-20 minutes of manual setup per event. If you handle 20+ shows a year, it adds up.

What if you could just run:

python create_event.py --show "MEDICA" --year 2026
Enter fullscreen mode Exit fullscreen mode

And have pretix auto-populated with the correct dates, location, and metadata?

The Data: Open Trade Show Calendar

There's an open-source dataset on GitHub that maintains structured data for 60+ major trade shows worldwide:

LensmorOfficial/trade-show-calendar — CSV and JSON formats, MIT licensed.

Here's what the JSON looks like:

{
  "name": "MEDICA",
  "website": "https://www.medica-tradefair.com/",
  "city": "Dusseldorf",
  "country": "Germany",
  "start_date": "2026-11-16",
  "end_date": "2026-11-19",
  "frequency": "Annual",
  "industry": "Healthcare & Medical",
  "region": "Europe",
  "notes": "World's largest medical trade fair"
}
Enter fullscreen mode Exit fullscreen mode

Clean, consistent schema. Exactly what we need for automation.

The Tool: pretix REST API

pretix exposes a REST API for everything — including event creation. The key endpoint is:

POST /api/v1/organizers/{organizer}/events/
Enter fullscreen mode Exit fullscreen mode

With fields like name, slug, date_from, date_to, location, currency, timezone, and meta_data.

Let's Build It

Step 1: Load the Trade Show Data

import json
import requests
from datetime import datetime

def load_trade_shows(source="github"):
    """Load trade show data from the open dataset."""
    if source == "github":
        url = ("https://raw.githubusercontent.com/"
               "LensmorOfficial/trade-show-calendar/"
               "main/data/trade_shows.json")
        resp = requests.get(url)
        resp.raise_for_status()
        return resp.json()
    else:
        with open("trade_shows.json") as f:
            return json.load(f)

def find_show(shows, name):
    """Find a trade show by name (case-insensitive)."""
    name_lower = name.lower()
    for show in shows:
        if name_lower in show["name"].lower():
            return show
    return None
Enter fullscreen mode Exit fullscreen mode

Step 2: Map Trade Show Data to pretix Event Schema

Different countries mean different currencies and timezones. Let's handle that:

# Mapping countries to currencies and timezones
COUNTRY_CONFIG = {
    "Germany": {"currency": "EUR", "timezone": "Europe/Berlin"},
    "United States": {"currency": "USD", "timezone": "America/New_York"},
    "China": {"currency": "CNY", "timezone": "Asia/Shanghai"},
    "Japan": {"currency": "JPY", "timezone": "Asia/Tokyo"},
    "UAE": {"currency": "AED", "timezone": "Asia/Dubai"},
    "Spain": {"currency": "EUR", "timezone": "Europe/Madrid"},
    "France": {"currency": "EUR", "timezone": "Europe/Paris"},
    "Brazil": {"currency": "BRL", "timezone": "America/Sao_Paulo"},
    "Singapore": {"currency": "SGD", "timezone": "Asia/Singapore"},
}

def to_pretix_event(show):
    """Convert trade show data to pretix event payload."""
    country = show["country"]
    config = COUNTRY_CONFIG.get(country, {
        "currency": "USD",
        "timezone": "UTC"
    })

    slug = (show["name"]
            .lower()
            .replace(" ", "-")
            .replace("(", "")
            .replace(")", "")[:50])

    return {
        "name": {"en": show["name"]},
        "slug": slug,
        "date_from": f"{show['start_date']}T09:00:00Z",
        "date_to": f"{show['end_date']}T18:00:00Z",
        "location": {"en": f"{show['city']}, {show['country']}"},
        "currency": config["currency"],
        "timezone": config["timezone"],
        "is_public": False,  # Start as draft
        "meta_data": {
            "industry": show.get("industry", ""),
            "frequency": show.get("frequency", ""),
            "website": show.get("website", ""),
        },
    }
Enter fullscreen mode Exit fullscreen mode

Step 3: Create the Event in pretix

PRETIX_URL = "https://pretix.eu/api/v1"
PRETIX_TOKEN = "your-api-token-here"
ORGANIZER = "your-organizer-slug"

def create_pretix_event(event_data):
    """Create an event in pretix via the REST API."""
    resp = requests.post(
        f"{PRETIX_URL}/organizers/{ORGANIZER}/events/",
        json=event_data,
        headers={
            "Authorization": f"Token {PRETIX_TOKEN}",
            "Content-Type": "application/json",
        },
    )
    resp.raise_for_status()
    return resp.json()
Enter fullscreen mode Exit fullscreen mode

Step 4: Add Default Ticket Types

Trade shows typically need specific ticket categories:

TRADE_SHOW_TICKETS = [
    {
        "name": {"en": "Visitor Pass"},
        "default_price": "0.00",
        "admission": True,
    },
    {
        "name": {"en": "Exhibitor Badge"},
        "default_price": "0.00",
        "admission": True,
    },
    {
        "name": {"en": "VIP / Buyer Pass"},
        "default_price": "50.00",
        "admission": True,
    },
    {
        "name": {"en": "Press Pass"},
        "default_price": "0.00",
        "admission": True,
    },
]

def add_ticket_types(event_slug):
    """Add default trade show ticket types to an event."""
    created = []
    for ticket in TRADE_SHOW_TICKETS:
        resp = requests.post(
            f"{PRETIX_URL}/organizers/{ORGANIZER}"
            f"/events/{event_slug}/items/",
            json=ticket,
            headers={
                "Authorization": f"Token {PRETIX_TOKEN}",
                "Content-Type": "application/json",
            },
        )
        resp.raise_for_status()
        created.append(resp.json())
    return created
Enter fullscreen mode Exit fullscreen mode

Putting It All Together

def setup_trade_show(show_name):
    """One command to create a fully configured trade show event."""
    # Load data
    shows = load_trade_shows()
    show = find_show(shows, show_name)

    if not show:
        print(f"Trade show '{show_name}' not found in dataset.")
        print("Available shows:")
        for s in shows:
            print(f"  - {s['name']}")
        return

    # Create event
    event_data = to_pretix_event(show)
    event = create_pretix_event(event_data)
    print(f"Created event: {event['name']['en']}")
    print(f"  Dates: {show['start_date']} to {show['end_date']}")
    print(f"  Location: {show['city']}, {show['country']}")
    print(f"  URL: {event['public_url']}")

    # Add ticket types
    tickets = add_ticket_types(event["slug"])
    print(f"  Added {len(tickets)} ticket types")

    return event

# Usage
setup_trade_show("MEDICA")
setup_trade_show("CES")
setup_trade_show("LogiMAT")
Enter fullscreen mode Exit fullscreen mode

Output:

Created event: MEDICA
  Dates: 2026-11-16 to 2026-11-19
  Location: Dusseldorf, Germany
  URL: https://pretix.eu/your-org/medica/
  Added 4 ticket types
Enter fullscreen mode Exit fullscreen mode

Batch Setup: All Shows in a Region

Need to set up ticketing for every European show in Q3-Q4? Easy:

from datetime import date

def setup_region(region, after_date=None):
    """Batch-create events for all shows in a region."""
    shows = load_trade_shows()
    count = 0

    for show in shows:
        if show["region"] != region:
            continue
        if after_date:
            start = date.fromisoformat(show["start_date"])
            if start < after_date:
                continue

        event_data = to_pretix_event(show)
        event = create_pretix_event(event_data)
        add_ticket_types(event["slug"])
        count += 1
        print(f"  [{count}] {show['name']}"
              f"{show['start_date']}")

    print(f"\nCreated {count} events for {region}")

# Set up all European shows from July onwards
setup_region("Europe", after_date=date(2026, 7, 1))
Enter fullscreen mode Exit fullscreen mode

Going Further

A few ideas to extend this:

Add exhibitor data. pretix has an Exhibitors API endpoint. You could pre-populate exhibitor lists from previous years' data.

Automate annually. Most trade shows happen on the same schedule every year. A cron job could create next year's events automatically when the dataset updates.

Enrich with more data. The awesome-trade-shows list includes 100+ shows across 16 industries — useful for discovering which shows to add to your pipeline.

Contribute back. Both the dataset and pretix are open source. If your show is missing from the calendar, submit a PR.

Why Open Data Matters for Events

The trade show industry has been one of the last holdouts against open, structured data. Flight data has APIs. Weather data has APIs. Financial data has APIs. But trade shows? You're still copying dates from PDFs.

Open datasets like trade-show-calendar won't solve everything, but they're a start. Combined with open-source tools like pretix, we can build automation that saves real time for real event organizers.

If you work in the trade show industry, consider contributing to these projects. The more complete the data, the more useful it becomes for everyone.


Resources:

Top comments (0)