# Developers
Everything on this site comes from a public JSON API. It needs no key. The [interactive reference](https://api.eventing.ing/docs) and the [OpenAPI document](https://api.eventing.ing/openapi.json) are on the API host. Agents can read this page as [/llms.txt](/llms.txt).
## Search API
Base URL: [https://api.eventing.ing](https://api.eventing.ing). It needs no auth, returns JSON, and allows CORS from anywhere.
- OpenAPI 3.1: [https://api.eventing.ing/openapi.json](https://api.eventing.ing/openapi.json). Interactive docs are at [https://api.eventing.ing/docs](https://api.eventing.ing/docs).
- Guide for people: [https://eventing.ing/developers](https://eventing.ing/developers).
- Longer version of this file, with every parameter: [https://eventing.ing/llms-full.txt](https://eventing.ing/llms-full.txt).
### Worked examples
- Tech events in Austin this weekend: `GET /events/search?near=austin&date=weekend&category=tech&tz=America/Chicago`
- Free events tonight in the Bay Area: `GET /events/tonight?near=bay-area&price=free&tz=America/Los_Angeles`
- A keyword in the next 30 days: `GET /events/search?q=rust&near=seattle&date=next-30&tz=America/Los_Angeles`
- One event: `GET /events/{id}`, using the `id` a search row carries (`evnt_…`). Its page is the row's `eventingUrl`.
- Organizers by name: `GET /organizers?q=python`
### Rules that matter
- Send `tz` as an IANA zone. `today`, `weekend` and friends are cut in it, and the response echoes it as `zone`.
- `near` takes a metro key, a city, a US ZIP or `lat,lon`. `radius` is in miles, default 50. The response says what `near` resolved to in `resolvedNear`. Leave `near` out for nationwide.
- Multi-valued filters are comma lists, unioned: `date=today,tomorrow`, `category=tech,music`.
- `date` windows: `today`, `tomorrow`, `this-week`, `weekend`, `next-week`, `next-7`, `next-30`, `later`, and `day-2`…`day-6`. For a range, use `from` and `to` (ISO 8601). A date-only `to` includes that whole day.
- `time` is the part of the day by start hour in `tz`: `morning`, `afternoon`, `evening` (17–22), `late`. Or `after`/`before=HH:MM`.
- An unknown parameter or an invalid value is a 400. Its body names the parameter and lists the valid values.
- `page` is 0-based. `size` is at most 200, default 50. `total` counts distinct events.
- Rows are about 1.4 KB each. `fields=compact` sends `id`, `title`, `startAt`, `endAt`, `timezone`, `city`, a price summary, `url` and `eventingUrl`, under a third of the size. Or name fields: `fields=id,title,startAt,price.kind`.
### Learning valid values
- `GET /events/facets?<same params as search>`: counts per date, time, region, category, organizer, tag and platform.
- `GET /metros`: metro keys, each a `near` value.
- `GET /events/place?near=78701`: what a `near` value resolves to.
### From a site URL to an API call
A site URL such as `https://eventing.ing/events?near=austin&date=weekend&category=tech` uses the API's parameter names. Move them onto `/events/search` with four changes:
- The site's `page` is 1-based and the API's is 0-based.
- The site defaults `near` to 94301 (Palo Alto) with `radius=50`; the API defaults to nationwide.
- The site uses the browser's zone; send `tz`.
- Drop the site-only keys `view`, `week`, `days`, `mine` and `event`.
### Usage
No key and no signup. Keep to about one request a second, cache responses for 60 seconds, and link each event you show to its `eventingUrl`. Don't page through the legacy `GET /events`; use `/events/search`.
## Pages
- [Events](https://eventing.ing/events): search with filters, a list and a map.
- [Tonight](https://eventing.ing/tonight): what's on this evening near you.
- [Metros](https://eventing.ing/metros): each metro's week, e.g. [Austin](https://eventing.ing/metros/austin).
- [Organizers](https://eventing.ing/organizers): hosts and their upcoming events.
- [The data](https://eventing.ing/data): what we hold, how we count it, and what we know is wrong.
- [Developers](https://eventing.ing/developers): the API, for people.
- [About](https://eventing.ing/about)
## Search parameters
Shared by `/events/search`, `/events/facets`, `/events/map` and `/events/days`. Every one is optional.
- `q`: full text over title, organizers and description, ranked.
- `date`: named windows as a comma list, cut in `tz`. `weekend` is Saturday and Sunday: asked on a Friday it leaves Friday out, and asked on a weekend day it starts today. `next-week` is the Monday to Sunday after the coming weekend. `day-<n>` is n days out, offered only before the weekend.
- `from`, `to`: ISO 8601 bounds. A date-only value is a local wall date in `tz`, and a date-only `to` includes that whole day, so `from=2026-10-12&to=2026-10-14` is three days. A full timestamp `to` is exclusive. Without `from`, events that have already started are left out; `from` replaces that floor.
- `time`: parts of the day as a comma list, by the start's local hour in `tz`: `morning` 05–12, `afternoon` 12–17, `evening` 17–22, `late` 22–05. It intersects `date`, so `date=tomorrow&time=evening` is tomorrow night. `late` is an hour of the day: with `date=tomorrow` it means tomorrow after 22:00 and before 05:00, not the small hours after tomorrow night. Free events near 94103 tomorrow night: `GET /events/search?near=94103&date=tomorrow&time=evening&price=free&tz=America/Los_Angeles`.
- `after` and `before`: a clock range on the start's local time in `tz`, `HH:MM`, 24-hour. `after` is inclusive and `before` exclusive, and either can be sent alone. When `after` is later than `before` the range wraps midnight: `after=22:00&before=02:00`. It intersects `time` and `date`: things starting 18:30–21:00 near Austin this weekend are `GET /events/search?near=austin&date=weekend&after=18:30&before=21:00&tz=America/Chicago`. The `time` facet counts are drawn without it.
- `region`: region keys. `unplaced`, `online` and `not-online` are pseudo-regions.
- `price`: `free`, `paid`, `unknown`. Unknown is its own tier and never counts as free.
- `format`: `in-person`, `online`, `hybrid`, `unknown`.
- `organizer`: organizer ids (`orgz_…`) from `/organizers?q=` or the facets.
- `tag`: a literal tag, spelled the way the organizer or platform spelled it.
- `category`: our topic taxonomy: `tech`, `ai`, `engineering`, `deep-tech`, `startups`, `hackathon`, `community`, `arts-culture`, `business`, `food-drink`, `health-wellness`, `sports-outdoors`, `lifestyle`, `causes`, `family-education`. `tech` is a parent and counts everything under it.
- `source`: platform keys, as the `source` facet lists them. These are not the feed keys `/events/sources` lists.
- `list`: a curated list by its mark, as `/events/sources` shows it: every event that list identified, past or upcoming. Add `from`/`to` to reach the past.
- `near`: a metro key, city, US ZIP or `lat,lon`. Absent means nationwide. A value that resolves to nothing is a 400.
- `radius`: miles around `near`, 1 to 500, default 50. Ignored without `near`.
- `tz`: the IANA zone every day boundary is drawn in. Without it, the zone is `near`'s, else the region's metro's, else the zone most metros share. The response's `zone` says which one was used.
- `page`: 0-based. `size`: 1 to 200, default 50.
`/events/search` and `/events/tonight` also take `fields`: a comma list of row fields, `compact` for the agent shape, and `price.kind`\-style paths inside an object. `id` is always sent. `/events/tonight` takes `near`, `tz`, `price=free` and `fields`. `/events/days` also takes `evenings=1`, which adds each day's leading evening category.
### `category` or `tag`
`category` is our own taxonomy. Every event from every platform is classified into it, so `category=ai` finds AI events whatever each organizer called them. `tag` matches one literal string, so it finds only events whose source used exactly that spelling. Use `category` for a topic. Use `tag` only for a specific label you saw in the `tag` facet, such as a conference's own hashtag.
## Where valid values come from
- Dates, parts of the day, regions, categories (including subcategories such as `ai`), organizers, tags and platforms: `GET /events/facets` with the same params as your search. It returns the values valid right now, and their counts. Date windows change with the day of the week, so read them from here rather than hard-coding them.
- Metro keys for `near`: `GET /metros`.
- An organizer id from a name: `GET /organizers?q=<name>`, then `organizer=orgz_…`.
- `source=` values: the `source` facet. `GET /events/sources` lists feed keys such as `eventbrite-search:austin`, which are not `source` values.
## Endpoints
- `GET /events/search`: upcoming events, filtered and paged.
- `GET /events/facets`: counts per value of every filter, for the same params.
- `GET /events/days`: distinct events per local day between `from` and `to`.
- `GET /events/map`: the same search as map points.
- `GET /events/tonight`: tonight in one metro, with tomorrow's count.
- `GET /events/{id}`: one event in full, with its description and the same event on other platforms.
- `GET /events/place?near=`: what `near` resolves to. `GET /events/places?q=&size=`: suggestions for `near`.
- `GET /organizers?q=`, `GET /organizers/{id}`: organizers and their numbers.
- `GET /metros`, `GET /metros/{key}`: each metro's week, with its organizers, its quiet list and its weekly letter.
- `GET /data`: what the corpus holds and how complete it is.
## Reading a response
- A search returns `events`, `total`, `page`, `size`, `zone` and `resolvedNear`.
- One row per real-world event. When the same event is listed on several platforms, or several times on one, the listings collapse into the richest of them. `total` counts distinct events, not listings. A row's `duplicateCount` is how many listings it stands for, itself included. `GET /events/{id}` lists the other listings in `alsoOn`.
- Rows leave out `description`; `GET /events/{id}` has it.
- Every endpoint's rows are one schema, `EventListing`. Tonight rows add `distanceMiles` and `rank`. Map points carry a subset of its fields, plus `platforms` and `organizerReach`.
- Times are ISO 8601 instants. A row's `timezone` is the event's own zone, and `zone` on the response is the zone "today" was cut in.
- `price.kind` is `free`, `paid` or `unknown`, with `minCents` and `currency` where the source gives them. `address` is null when the source hides it from non-guests; `addressVisibility` says so.
## Usage policy
- No key, no signup and no auth. CORS is open.
- Fair use: about one request a second, sustained. Nothing enforces a limit today.
- Cache any response for 60 seconds. The corpus updates nightly, so a fresher answer rarely differs.
- Attribution: when you show an event, link its `eventingUrl`. It carries every listing we found, while the source `url` is only one of them.
- Use `/events/search`, not the legacy `GET /events`, which exists for old clients.