@chrischall/eventbrite-mcp 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +34 -0
- package/.claude-plugin/plugin.json +21 -0
- package/.mcp.json +11 -0
- package/LICENSE +21 -0
- package/README.md +100 -0
- package/dist/bundle.js +40401 -0
- package/dist/client.js +76 -0
- package/dist/discovery.js +530 -0
- package/dist/eventbrite-auth.js +18 -0
- package/dist/index.js +31 -0
- package/dist/tools/account.js +170 -0
- package/dist/tools/discovery.js +126 -0
- package/dist/tools/events.js +131 -0
- package/dist/tools/lookup.js +96 -0
- package/dist/tools/params.js +39 -0
- package/dist/transport-fetchproxy.js +57 -0
- package/dist/transport.js +5 -0
- package/dist/version.js +1 -0
- package/package.json +72 -0
- package/server.json +29 -0
- package/skills/eventbrite/SKILL.md +70 -0
- package/skills/eventbrite/references/discovery-api.md +113 -0
- package/skills/eventbrite/references/token-api.md +102 -0
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@chrischall/eventbrite-mcp",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"mcpName": "io.github.chrischall/eventbrite-mcp",
|
|
5
|
+
"description": "Eventbrite MCP server for Claude — developed and maintained by AI (Claude Code)",
|
|
6
|
+
"author": "Claude Code (AI) <https://www.anthropic.com/claude>",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/chrischall/eventbrite-mcp.git"
|
|
10
|
+
},
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"mcp",
|
|
14
|
+
"model-context-protocol",
|
|
15
|
+
"claude",
|
|
16
|
+
"ai",
|
|
17
|
+
"eventbrite",
|
|
18
|
+
"events",
|
|
19
|
+
"tickets",
|
|
20
|
+
"event-discovery",
|
|
21
|
+
"orders"
|
|
22
|
+
],
|
|
23
|
+
"type": "module",
|
|
24
|
+
"bin": {
|
|
25
|
+
"eventbrite-mcp": "dist/index.js"
|
|
26
|
+
},
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist",
|
|
32
|
+
".claude-plugin",
|
|
33
|
+
"skills/",
|
|
34
|
+
".mcp.json",
|
|
35
|
+
"server.json"
|
|
36
|
+
],
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "tsc && npm run bundle",
|
|
39
|
+
"bundle": "esbuild src/index.ts --bundle --platform=node --format=esm --external:dotenv --banner:js='import { createRequire as __createRequire } from \"module\"; const require = __createRequire(import.meta.url);' --outfile=dist/bundle.js",
|
|
40
|
+
"dev": "node dist/index.js",
|
|
41
|
+
"test": "vitest run",
|
|
42
|
+
"test:watch": "vitest",
|
|
43
|
+
"test:coverage": "vitest run --coverage",
|
|
44
|
+
"worker:dev": "wrangler dev",
|
|
45
|
+
"worker:deploy": "wrangler deploy",
|
|
46
|
+
"worker:test": "vitest run --config vitest.workers.config.ts"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@chrischall/mcp-utils": "^0.14.0",
|
|
50
|
+
"@fetchproxy/server": "^1.7.0",
|
|
51
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
52
|
+
"dotenv": "^17.4.0",
|
|
53
|
+
"zod": "^4.4.2"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@chrischall/mcp-connector": "^1.1.1",
|
|
57
|
+
"@cloudflare/vitest-pool-workers": "^0.19.0",
|
|
58
|
+
"@cloudflare/workers-oauth-provider": "^0.8.1",
|
|
59
|
+
"@cloudflare/workers-types": "^5.20260708.1",
|
|
60
|
+
"@types/node": "^26.0.0",
|
|
61
|
+
"@vitest/coverage-v8": "^4.1.2",
|
|
62
|
+
"agents": "^0.19.0",
|
|
63
|
+
"esbuild": "^0.28.0",
|
|
64
|
+
"typescript": "^7.0.2",
|
|
65
|
+
"vitest": "^4.1.2",
|
|
66
|
+
"wrangler": "^4.110.0"
|
|
67
|
+
},
|
|
68
|
+
"allowScripts": {
|
|
69
|
+
"esbuild@0.28.1": true,
|
|
70
|
+
"workerd@1.20260722.1": true
|
|
71
|
+
}
|
|
72
|
+
}
|
package/server.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
|
+
"name": "io.github.chrischall/eventbrite-mcp",
|
|
4
|
+
"description": "Eventbrite for Claude — your tickets/orders, organizer data, and public event discovery",
|
|
5
|
+
"repository": {
|
|
6
|
+
"url": "https://github.com/chrischall/eventbrite-mcp",
|
|
7
|
+
"source": "github"
|
|
8
|
+
},
|
|
9
|
+
"version": "0.0.0",
|
|
10
|
+
"packages": [
|
|
11
|
+
{
|
|
12
|
+
"registryType": "npm",
|
|
13
|
+
"identifier": "@chrischall/eventbrite-mcp",
|
|
14
|
+
"version": "0.0.0",
|
|
15
|
+
"transport": {
|
|
16
|
+
"type": "stdio"
|
|
17
|
+
},
|
|
18
|
+
"environmentVariables": [
|
|
19
|
+
{
|
|
20
|
+
"name": "EVENTBRITE_TOKEN",
|
|
21
|
+
"description": "Personal OAuth token (eventbrite.com/platform/api-keys); needed for account tools",
|
|
22
|
+
"isRequired": false,
|
|
23
|
+
"format": "string",
|
|
24
|
+
"isSecret": true
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: eventbrite
|
|
3
|
+
description: "Query eventbrite.com from a shell — your tickets/orders, your organizations' events and attendees via the documented token API (curl), and public event discovery/search via the fpx browser bridge (the search API is WAF-walled and absent from the documented API). Use when you want Eventbrite data without an MCP server, in a script, or one-shot."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Eventbrite access (curl + fpx)
|
|
7
|
+
|
|
8
|
+
Two surfaces, two tools — match the tool to reachability:
|
|
9
|
+
|
|
10
|
+
1. **Documented API `https://www.eventbriteapi.com/v3`** — reachable
|
|
11
|
+
server-side with a personal OAuth token. Use plain `curl`. Covers your
|
|
12
|
+
identity, your orders/tickets, organizations you own (events, attendees,
|
|
13
|
+
orders), and any event **by id**. It has **no public event search** —
|
|
14
|
+
Eventbrite removed it from the documented API in 2019.
|
|
15
|
+
2. **Consumer site API `https://www.eventbrite.com/api/v3/destination/…`** —
|
|
16
|
+
WAF-blocked for any server-side client (returns an HTML "Whoops!" page).
|
|
17
|
+
Public event **search/discovery** lives only here, so those calls route
|
|
18
|
+
through the user's signed-in browser tab with `fpx`.
|
|
19
|
+
|
|
20
|
+
## One-time setup
|
|
21
|
+
|
|
22
|
+
**Token (curl surface):** create a private token at
|
|
23
|
+
<https://www.eventbrite.com/platform/api-keys> (free for any Eventbrite
|
|
24
|
+
account) and export it as `EVENTBRITE_TOKEN`.
|
|
25
|
+
|
|
26
|
+
**Bridge (fpx surface):**
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
npm install -g @fetchproxy/cli # provides `fpx`
|
|
30
|
+
fpx profile add eventbrite --domain eventbrite.com
|
|
31
|
+
fpx pair -p eventbrite # prints a pair code → approve in the Transporter popup
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Requires the **Transporter** extension with Chrome site access for
|
|
35
|
+
`eventbrite.com` and an open (signed-in for account data) eventbrite.com tab.
|
|
36
|
+
Pairing persists after the first approval.
|
|
37
|
+
|
|
38
|
+
## Core calls
|
|
39
|
+
|
|
40
|
+
Token surface — every request is:
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
curl -sS "https://www.eventbriteapi.com/v3/users/me/" \
|
|
44
|
+
-H "Authorization: Bearer $EVENTBRITE_TOKEN" | jq
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Bridge surface — stdout is data only, ready for `jq`:
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
fpx get 'https://www.eventbrite.com/api/v3/destination/events/?event_ids=<id>&expand=event_sales_status,primary_venue' \
|
|
51
|
+
-p eventbrite | jq '.events[0]'
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Ready-to-run request bodies and `jq` recipes: `references/token-api.md`
|
|
55
|
+
(curl surface) and `references/discovery-api.md` (fpx surface, incl. event
|
|
56
|
+
search). Read the relevant reference before composing a call — the search
|
|
57
|
+
body shape and the resolve-location-first rule live there.
|
|
58
|
+
|
|
59
|
+
## Rules
|
|
60
|
+
|
|
61
|
+
- **Resolve places before searching**: destination search takes place ids,
|
|
62
|
+
not free-text locations — autocomplete first (see `discovery-api.md`).
|
|
63
|
+
- **Pagination**: v3 responses carry a `pagination` envelope; loop with
|
|
64
|
+
`?continuation=<token>` while `has_more_items` is true.
|
|
65
|
+
- **fpx exit codes**: `2` bridge down (pair/approve in Transporter), `3` bot
|
|
66
|
+
wall (refresh a signed-in eventbrite.com tab), `4` upstream non-2xx.
|
|
67
|
+
- **Read-only**: these recipes only read data. The documented API supports
|
|
68
|
+
organizer writes (create/update events etc.) but they are out of scope
|
|
69
|
+
here — don't improvise write calls from this skill.
|
|
70
|
+
- Never log or commit the token or captured cookies.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Eventbrite discovery API (`www.eventbrite.com/api/v3/destination/…`) — fpx recipes
|
|
2
|
+
|
|
3
|
+
Public event search/discovery. WAF-blocked server-side; every call here goes
|
|
4
|
+
through the fpx bridge (`-p eventbrite`). Request shapes below were captured
|
|
5
|
+
live from the site's own network traffic (2026-07-30, web_app discover
|
|
6
|
+
v10.14.65).
|
|
7
|
+
|
|
8
|
+
## CSRF (search POST only)
|
|
9
|
+
|
|
10
|
+
GETs need nothing extra. The search POST requires the Django CSRF header,
|
|
11
|
+
whose value is the `csrftoken` cookie (32 chars, JS-readable). Read it
|
|
12
|
+
through the bridge — the profile must declare the cookie scope (see SKILL.md
|
|
13
|
+
setup):
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
CSRF=$(fpx cookies csrftoken -p eventbrite | jq -r '.csrftoken')
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
If the cookie is absent, load any eventbrite.com page in the browser first.
|
|
20
|
+
|
|
21
|
+
## Resolve a place id first
|
|
22
|
+
|
|
23
|
+
Searches take internal place ids (e.g. Charlotte NC = `85981333`), never
|
|
24
|
+
place names. The site itself resolves locations via Google Places, but the
|
|
25
|
+
scriptable route is the SSR page store: fetch the browse page for the
|
|
26
|
+
location slug and pull `placeId` out of the embedded `__SERVER_DATA__`:
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
# slug format: <state>--<city> (US) or <country>--<city>
|
|
30
|
+
fpx get 'https://www.eventbrite.com/d/co--denver/events/' -p eventbrite \
|
|
31
|
+
| grep -oE '"placeId":"[0-9]+"' | head -1
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The same SSR page embeds the full first page of results in
|
|
35
|
+
`search_data.events` — for a quick "what's on in <city>" that GET alone may
|
|
36
|
+
be all you need.
|
|
37
|
+
|
|
38
|
+
## Event search
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
CSRF=$(fpx cookies csrftoken -p eventbrite | jq -r '.csrftoken')
|
|
42
|
+
cat > /tmp/eb-search.json <<'EOF'
|
|
43
|
+
{
|
|
44
|
+
"browse_surface": "search",
|
|
45
|
+
"event_search": {
|
|
46
|
+
"q": "blues",
|
|
47
|
+
"places": ["85981333"],
|
|
48
|
+
"dates": ["current_future"],
|
|
49
|
+
"dedup": true,
|
|
50
|
+
"page": 1,
|
|
51
|
+
"page_size": 20
|
|
52
|
+
},
|
|
53
|
+
"expand.destination_event": [
|
|
54
|
+
"primary_venue", "image", "ticket_availability",
|
|
55
|
+
"event_sales_status", "primary_organizer"
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
EOF
|
|
59
|
+
fpx post-json 'https://www.eventbrite.com/api/v3/destination/search/' @/tmp/eb-search.json \
|
|
60
|
+
-p eventbrite -H "X-CSRFToken: $CSRF" -H "X-Requested-With: XMLHttpRequest" \
|
|
61
|
+
| jq '.events.results[] | {id, name, start: .start_date, venue: .primary_venue.name, url}'
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Body knobs (all inside `event_search`, all optional except you want at least
|
|
65
|
+
`q` or `places`):
|
|
66
|
+
|
|
67
|
+
- `q` — keyword text.
|
|
68
|
+
- `places` — array of place-id strings (resolve first, above).
|
|
69
|
+
- `dates` — array; `"current_future"` plus optionally one of `"today"`,
|
|
70
|
+
`"tomorrow"`, `"this_weekend"`; or `date_range: {from, to}` (ISO dates).
|
|
71
|
+
- `tags` — category/format filters: `"EventbriteCategory/<id>"` (103 =
|
|
72
|
+
Music …), `"EventbriteSubCategory/<id>"`, `"EventbriteFormat/<id>"`. Ids
|
|
73
|
+
match the documented API's `/categories/` etc. (see token-api.md).
|
|
74
|
+
- `online_events_only` — bool.
|
|
75
|
+
- `price` — `"free"` or `"paid"`.
|
|
76
|
+
- `page`, `page_size` (site uses 20), `dedup: true`.
|
|
77
|
+
|
|
78
|
+
Response: `{events: {pagination: {object_count, page_count, continuation},
|
|
79
|
+
results: [...]}, ...}` — paginate by incrementing `page`.
|
|
80
|
+
|
|
81
|
+
## Event detail by id (GET, no CSRF)
|
|
82
|
+
|
|
83
|
+
```sh
|
|
84
|
+
fpx get 'https://www.eventbrite.com/api/v3/destination/events/?event_ids=<id>,<id>&expand=primary_venue,image,ticket_availability,event_sales_status,primary_organizer' \
|
|
85
|
+
-p eventbrite | jq '.events[]'
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Event ids are the trailing digits in event URLs (`…-tickets-<id>`). For
|
|
89
|
+
full ticket-class detail prefer the documented API (`token-api.md`) —
|
|
90
|
+
`/events/<id>/` works for any public event with just a token.
|
|
91
|
+
|
|
92
|
+
## Your account data through the bridge (no token needed)
|
|
93
|
+
|
|
94
|
+
The www host proxies the documented v3 API with the browser session's auth,
|
|
95
|
+
so the whole `token-api.md` surface also works session-authed via fpx —
|
|
96
|
+
same paths, `www.eventbrite.com` host (live-verified: `/api/v3/users/me/`):
|
|
97
|
+
|
|
98
|
+
```sh
|
|
99
|
+
fpx get 'https://www.eventbrite.com/api/v3/users/me/orders/?expand=event&time_filter=current_future' \
|
|
100
|
+
-p eventbrite | jq '.orders[] | {id, event: .event.name.text}'
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Prefer the token + curl for scripts (no browser dependency); use this when
|
|
104
|
+
no token is configured.
|
|
105
|
+
|
|
106
|
+
## Gotchas
|
|
107
|
+
|
|
108
|
+
- A non-JSON 2xx body from any of these = the WAF interstitial leaked
|
|
109
|
+
through — refresh a signed-in eventbrite.com tab and retry.
|
|
110
|
+
- `log_requests` / `log_engagement` endpoints seen in captures are
|
|
111
|
+
analytics — don't call them.
|
|
112
|
+
- The `?stable_id=` query param on the site's own search calls is a client
|
|
113
|
+
analytics uuid — omit it.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Eventbrite documented API (`eventbriteapi.com/v3`) — curl recipes
|
|
2
|
+
|
|
3
|
+
Auth on every call: `-H "Authorization: Bearer $EVENTBRITE_TOKEN"`.
|
|
4
|
+
Personal token: <https://www.eventbrite.com/platform/api-keys>.
|
|
5
|
+
All endpoints end with a trailing slash — omitting it 301s.
|
|
6
|
+
|
|
7
|
+
> Verification status (2026-07-30): `eventbriteapi.com` reachability and the
|
|
8
|
+
> 401 error envelope are live-verified. Endpoint shapes were live-verified
|
|
9
|
+
> through the session-authed www-host variant of the same v3 API
|
|
10
|
+
> (`www.eventbrite.com/api/v3/…`): `/users/me/`, `/users/me/orders/`
|
|
11
|
+
> envelope, `/users/me/organizations/` envelope, `/categories/`, and
|
|
12
|
+
> `/events/<id>/?expand=venue,ticket_availability` on a public event.
|
|
13
|
+
> `/ticket_classes/`, `/description/`, `/attendees/`, `/venues/`,
|
|
14
|
+
> `/subcategories/`, `/formats/` follow the official API reference but
|
|
15
|
+
> weren't exercised — eyeball the first response before building on a field.
|
|
16
|
+
|
|
17
|
+
Shorthand used below:
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
eb() { curl -sS "https://www.eventbriteapi.com/v3$1" -H "Authorization: Bearer $EVENTBRITE_TOKEN"; }
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Identity
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
eb /users/me/ | jq '{id, name, email: .emails[0].email}'
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Your tickets / orders (attendee side)
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
# upcoming orders with the event expanded
|
|
33
|
+
eb '/users/me/orders/?expand=event&time_filter=current_future' \
|
|
34
|
+
| jq '.orders[] | {id, status, event: .event.name.text, start: .event.start.local}'
|
|
35
|
+
|
|
36
|
+
# one order with attendees (barcode-level detail)
|
|
37
|
+
eb '/orders/<order_id>/?expand=attendees' | jq
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`time_filter`: `all` | `current_future` | `past`.
|
|
41
|
+
|
|
42
|
+
## Organizations you belong to (organizer side)
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
eb /users/me/organizations/ | jq '.organizations[] | {id, name}'
|
|
46
|
+
|
|
47
|
+
# events for an org: status live|draft|started|ended|completed|canceled|all
|
|
48
|
+
eb '/organizations/<org_id>/events/?status=live&order_by=start_asc' \
|
|
49
|
+
| jq '.events[] | {id, name: .name.text, start: .start.local, url}'
|
|
50
|
+
|
|
51
|
+
# attendees / orders across the org
|
|
52
|
+
eb '/organizations/<org_id>/attendees/?status=attending' | jq '.attendees[] | {profile: .profile.name, email: .profile.email, event_id}'
|
|
53
|
+
eb '/organizations/<org_id>/orders/' | jq '.orders[] | {id, email, status}'
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Any event by id (works for public events, not just yours)
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
eb '/events/<event_id>/?expand=venue,organizer,ticket_availability' \
|
|
60
|
+
| jq '{name: .name.text, start: .start.local, end: .end.local, venue: .venue.name, is_free, status, url}'
|
|
61
|
+
|
|
62
|
+
eb '/events/<event_id>/ticket_classes/' | jq '.ticket_classes[] | {name, free, cost: .cost.display, on_sale_status}'
|
|
63
|
+
eb '/events/<event_id>/description/' | jq -r .description # full HTML description
|
|
64
|
+
eb '/events/<event_id>/attendees/' | jq # your own events only
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Event ids are the long digits in any event URL (`…-tickets-<event_id>`).
|
|
68
|
+
|
|
69
|
+
## Reference data
|
|
70
|
+
|
|
71
|
+
```sh
|
|
72
|
+
eb /categories/ | jq '.categories[] | {id, name}'
|
|
73
|
+
eb /subcategories/ | jq '.subcategories[] | {id, name}'
|
|
74
|
+
eb /formats/ | jq '.formats[] | {id, name}'
|
|
75
|
+
eb '/venues/<venue_id>/' | jq '{name, address: .address.localized_address_display}'
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Pagination
|
|
79
|
+
|
|
80
|
+
Every list response carries:
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{"pagination": {"object_count": 123, "page_size": 50, "has_more_items": true, "continuation": "..."}}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Loop with `?continuation=<token>` (repeat the original params) while
|
|
87
|
+
`has_more_items` is true. `page_size` max is generally 100 for org-level
|
|
88
|
+
lists, 50 elsewhere.
|
|
89
|
+
|
|
90
|
+
## Errors
|
|
91
|
+
|
|
92
|
+
Non-2xx bodies are JSON: `{"status_code": N, "error": "CODE",
|
|
93
|
+
"error_description": "..."}`. Live-verified examples: bad token →
|
|
94
|
+
`401 INVALID_AUTH`; missing CSRF (www host only) → `401 ACCESS_DENIED`.
|
|
95
|
+
`404 NOT_FOUND` for unknown ids; `429` when rate-limited (token buckets:
|
|
96
|
+
2,000 calls/hour per token by default).
|
|
97
|
+
|
|
98
|
+
## No search here
|
|
99
|
+
|
|
100
|
+
`GET /events/search/` was removed from this API (Dec 2019) — it now 404s.
|
|
101
|
+
Public event discovery only exists on the WAF-walled consumer surface; see
|
|
102
|
+
`discovery-api.md` (fpx bridge).
|