We needed a list of every place to play padel, tennis and pickleball in Mexico. Nobody sells a good one, so we built it from OpenStreetMap, and learned that an open map is a mirror of the people who edited it.
MeetAndPlay is a padel, tennis and pickleball app that launches in Cancún on 1 December 2026. An app that helps people find a game needs to know where the courts are, in a country with 32 states and a lot of places that never made it into a booking platform. We built a nationwide directory, the court directory at meetandplay.mx/canchas, on top of OpenStreetMap. This post covers the pipeline, the licence, and the quality problems we found, with the real numbers from our latest snapshot.
Why OpenStreetMap
The alternatives were scraping a booking marketplace, buying a commercial POI dataset, or using a map provider's places API. We rejected each for a different reason: terms of service, price, and licences that forbid storing and re-publishing the data. OpenStreetMap is the only source that lets you pull the data, keep it, build pages from it, and re-publish what you derive, provided you follow the Open Database Licence (ODbL 1.0) and credit contributors.
The pipeline
The pipeline is a plain script, run by hand when we want a refresh. There is no scheduler and no live dependency on the Overpass API at request time.
- Pull. Query the Overpass API for features tagged with a racket sport (
sport=tennis,sport=padel,sport=pickleball). Our latest pull has the snapshot timestamp2026-09-25T20:14:17Z. The timestamp travels with the data, so every page and every number can say how old it is. - Filter. The most important step. Tennis courts are everywhere in OSM: schools, universities, apartment complexes. We keep facilities that make sense as a place to play and exclude school and university campuses. One filter function is shared by every consumer, because two copies of "what counts as a venue" drift apart within a week.
- Locate. Assign each place to a state and municipality from OSM's administrative boundaries, matched against INEGI's municipality list. Reverse-geocode a colonia and street with Nominatim, because an OSM point alone is not an address. Compute the distance to a coastline from Natural Earth, which turns out to be useful on a beach-heavy market.
- Sanitize. OSM contact tags are free text edited by anyone. A "website" value can be a
javascript:URL; a "phone" can have no digits. We drop anything that cannot be a safe link at build time, and the render layer checks again. - Aggregate. Write state and city indexes as generated TypeScript modules. Static data means no database call to render a directory page.
The rule that guided everything: no invented data. If OSM has no name for a place, the page gets no name. We label it from its sport and colonia at render time instead of guessing. That sounds like a small thing and it prevents the whole class of bug where an app confidently shows a made-up club.
What the snapshot says
Counting everything in the snapshot, OSM has 1,052 places across all 32 states and 255 cities, carrying a total of 2,307 courts. Only 354 places have a name, a third of the total.
Per sport, counted as places carrying that sport tag:
| Sport | Places in OSM |
|---|---|
| Tennis | 1,005 |
| Padel | 51 |
| Pickleball | 14 |
A caution that cost us an embarrassing correction in draft: OSM counts places per sport, not courts per sport. A club with a padel court and two tennis courts is one place in the padel column and one in the tennis column. So our tables say "places with padel", never "padel courts". The 2,307 courts figure is the total across every sport and cannot be split.
Two results made us rethink the directory:
- Padel is almost invisible on the open map. 51 places in the whole country is far below what the sport's own federation says exists. The International Padel Federation published, in March 2025, "more than 630 clubs" and 2,300 courts for Mexico. Those are their figures, from their research department, and we label them directional: we cannot audit them and we do not divide one number by the other. But the gap exists, and it is the finding.
- Cancún looks like a tennis town on OSM. The map has 35 places and 58 courts in Cancún, all of them tagged tennis, none tagged padel, and none with a name. A city where padel is the headline sport has no padel in OSM. By state, the places with padel are concentrated where a few mappers care: Yucatán 8, Sonora 7, Coahuila 6, Jalisco 5. Quintana Roo, which has 71 places, has 0.
An open map reflects who edits it. That is the lesson to carry to any OSM-derived project: your coverage is a coverage of mappers, not of the world.
The licence, in practice
I am not a lawyer and this is not legal advice, but here is how we handled ODbL, which is the thing people get wrong.
- Attribution on every page that uses the data, as "© OpenStreetMap contributors", linked to the licence. No exceptions for a footer you can't see.
- Share-alike applies to derived databases. Anything we publish as data (our per-state CSV, our dataset markup) is offered under ODbL with the same credit.
- Keep the licensed data separate from data that isn't. We also research venues by hand from public sources, each row citing its source URL. Those rows are not OSM's and are not ODbL. If we merged them into the same published dataset, we would either relicense them or contaminate the OSM-derived release. So the published report and CSV read only the OSM-derived modules. The directory's own totals, which also count the hand-researched venues, never appear in the ODbL-labelled outputs. In code this is the difference between two exported objects, and a comment in the module saying not to mix them.
Publishing the result
Because the dataset is ODbL, we put it out as a report with a downloadable CSV: per-state places, courts, and places per sport, plus the methodology and the caveats above. The CSV has Spanish snake_case column names and is served from a path with a dot in it on purpose, so our locale-rewriting middleware leaves it alone and it is the same in every language.
All numbers on the page are derived from the same module that builds the CSV. We never type a figure by hand. If we re-pull OSM, the page, the file and the structured data move together.
Quality problems you will hit
- Duplicates. The same club mapped as a point, a polygon and a relation. Dedupe by proximity and name, not by ID.
- Wrong sport tags. A tennis court re-lined for pickleball keeps the tennis tag. Do not infer sport counts beyond what is tagged.
- Closed and abandoned places. OSM has lifecycle prefixes, and not everyone uses them. We say clearly that the directory is what mappers recorded, not what any club verified.
- Municipality edges. Border points flip between adjacent municipalities in different data vintages.
What we would tell you to do
- Version your snapshot and print its timestamp wherever a number appears.
- Decide what counts as a venue once, in one function.
- Never mix licences in one published file.
- Treat a gap between OSM and an outside source as a feature of your report, not a bug in your pipeline. That is also an invitation: if you play in Cancún and you know where the padel courts are, adding them to OpenStreetMap makes the map better for everyone, not just us.
If you want to poke at the data, the CSV is public, the code is in the canchas-mexico repo on GitHub, and we would like to hear what you build from it.
Data © OpenStreetMap contributors, ODbL 1.0. Snapshot 2026-09-25T20:14:17Z. External figure: FIP, "Focus en… México", 11 March 2025.