The event platform agents can actually use.
17 documented tools — 10 read, 7 write, 4 answering without a key — served over REST, described by one OpenAPI document, and mirrored over MCP. Same authorization, same error shape, same rows as the console.
# Discover the surface — no credential needed
curl -s https://turnout.teraai.cc/api/agent/v1/tools
# Read the public event feed
curl -s 'https://turnout.teraai.cc/api/agent/v1/events?city=San+Francisco&pageSize=3'
# Call a write tool with a scoped key
curl -s https://turnout.teraai.cc/api/agent/v1/tools/create_event \
-H "authorization: Bearer $TURNOUT_AGENT_TOKEN" \
-H 'content-type: application/json' \
-d '{"name":"Launch night","startsAt":"2027-03-01T19:00:00Z","timezone":"Europe/Berlin","capacity":120}'{
"mcpServers": {
"turnout": {
"url": "https://turnout.teraai.cc/api/agent/v1/mcp",
"headers": {
"authorization": "Bearer $TURNOUT_AGENT_TOKEN"
}
}
}
}The MCP server exposes the same tool names and arguments. Without a credential it still answers the public read tools, which is enough for search and discovery inside an agent workspace.
Every tool, with its schema and its permissions
Generated from the registry on this request. Expand a tool to see the JSON schema the executor validates against, the scopes it needs, and a call you can run.
Searches two sources and returns them in one list, each row tagged with `origin`. "turnout" rows are events an organizer published on Turnout, read live from Turnout's own database — the primary source. "discover" rows are the imported third-party catalogue (San Francisco), subject to its own licence. Own events are listed first. Draft, cancelled, private and fixture events are never returned by either source, so a row an agent sees is a row its public page shows. Fields Turnout does not record (end time, address, city, price, category for own events) are null with a notice, never guessed.
Use when you need to know what is happening: to find an organizer's published event to offer a user, to find comparable events, to check whether a date is busy, or to answer a question about a place, category or timeframe.
- ✕ Attendance, conversion or demand numbers — neither public source carries them. Use the credentialed analytics tools.
- ✕ One known slug — use get_event.
- Endpoint
- /api/agent/v1/tools/discover_events
- Version
- v1
- Scopes
- none — public
- Idempotency
- optional
- Side effects
- none
{
"type": "object",
"properties": {
"query": {
"type": "string",
"minLength": 2,
"maxLength": 120
},
"city": {
"type": "string",
"minLength": 2,
"maxLength": 60
},
"neighbourhood": {
"type": "string",
"minLength": 2,
"maxLength": 60
},
"category": {
"type": "string",
"minLength": 2,
"maxLength": 60
},
"dateFrom": {
"type": "string",
"minLength": 4,
"maxLength": 40,
"description": "ISO 8601 date or timestamp, e.g. 2026-12-01 or 2026-12-01T19:00:00Z"
},
"dateTo": {
"type": "string",
"minLength": 4,
"maxLength": 40,
"description": "ISO 8601 date or timestamp, e.g. 2026-12-01 or 2026-12-01T19:00:00Z"
},
"free": {
"type": "boolean"
},
"mode": {
"type": "string",
"enum": [
"in_person",
"online"
]
},
"sort": {
"type": "string",
"enum": [
"soonest",
"latest"
]
},
"source": {
"type": "string",
"enum": [
"both",
"turnout",
"catalogue"
]
},
"page": {
"type": "integer",
"minimum": 1,
"maximum": 500
},
"pageSize": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"description": "Rows per page (1-100)."
}
},
"additionalProperties": false
}curl -s https://turnout.teraai.cc/api/agent/v1/tools/discover_events \
-H 'content-type: application/json' \
-d '{"query":"pottery","dateFrom":"2026-12-01","pageSize":10}'Find pottery events in December.
Scopes, and what each one unlocks
A credential carries an explicit scope list. Reads are separate from writes, and the two destructive actions carry an extra confirmation.
| Scope | What it allows |
|---|---|
| events:read | Read public event data (the Discover catalogue) and the organization's own events. |
| organizers:read | Read public organizer profiles. |
| analytics:read | Read the organization's own first-party metrics, including the credential's own call budget. |
| rsvp:write | Create a registration on a published event. Records a real participant, so it is never granted by default. |
| events:write | Create and change the organization's own events: drafts, edits, publishing and cancelling. Publishing and cancelling also require `confirm: true` on the call. |
| campaigns:write | Draft a campaign and queue its reminders. Queuing writes reminder rows; nothing is sent by Turnout in this build. |
Credentials are issued by an organizer
Keys are minted inside the console, scoped at creation, and revocable at any time. A key that has never been used is also the one that is easiest to remove: every call is logged against it, so usage is visible before you revoke.
- ▸ Token format and rotation handled server-side
- ▸ Per-call ledger: tool, status, credential
- ▸ No scope grants a send action — Turnout does not deliver messages in this build
Search the public event feed as an agent would
No key, no writes, no side effects. The panel calls GET /api/agent/v1/events from your browser and shows exactly what comes back — including errors and rate limits.
| Event | City | Starts | Price | Mode |
|---|