Fetch events as an agent
For an agent (a model, a pipeline, a script) that needs the events QuickLookup publishes — holidays, sports fixtures, promotions, festivals, seasons and any customer feed it may see — with their dates, places and classification. Everything below is what the live service answers; copy the request bodies as they are.
Which door
| you are | use |
|---|---|
| an MCP-capable agent client | POST /mcp with the tools list_data_services → get_data_service → query_data_service, or search_nearby_events. Every request carries the protocol version 2026-07-28 in the MCP-Protocol-Version header and in params._meta (io.modelcontextprotocol/protocolVersion), the client capabilities in params._meta (io.modelcontextprotocol/clientCapabilities, {} is enough) and the method in an Mcp-Method header; see REST, MCP, and semantic clients |
| a script or a pipeline | the REST calls below |
Both take the same bearer token; the token decides which feeds you see. Every call is read-only.
1. Find the feeds
GET https://quicklookup.com/api/v1/catalog/services?type=event
Authorization: Bearer <your API key>
Each item carries serviceGid (the feed's identity), label, detailUrl and queryUrl.
Follow detailUrl once: it lists the feed's eventTypes, the fields it publishes, its
inputs (some feeds need one, such as a country), the page and interval limits, and a ready
example request.
2. Fetch a period
POST https://quicklookup.com/api/v1/events/query
Content-Type: application/json
{
"collectionGid": "<serviceGid>",
"from": "2026-01-01T00:00:00Z",
"to": "2027-01-01T00:00:00Z",
"fields": ["subType", "countryCode", "venue", "location", "properties", "influence"],
"limit": 1000
}
fromis inclusive,toexclusive, both UTC with an offset. The period defines the complete result; rows come a page at a time — repeat the same body with"cursor": "<nextCursor>"untilnextCursoris null.limitgoes up to 10,000.fieldsnames the optional fields you want beyond the ones every event has (gid,name,type,dateFrom,dateTo,allDay,flags). Only fields the feed publishes are accepted; the detail page lists them. The blocks —sites,participants,media,names,classification— come with every event and need no naming.- Narrow with
eventTypes,subTypes,countryCodes,venues,statuses,attendanceModes, or a textq(only where the feed publishesname; otherwise it is refused naming the field); addnear: {longitude, latitude, radiusKm}for a place;orderisstarts_asc(default),starts_desc,distance_ascordistance_desc. - Feeds that fetch on demand (holidays, sports) answer from the source the first time and
from storage afterwards; the response's
coveragesays which part of your period was served andsourcesays where it came from. - A feed that needs an input (holidays need a country) takes it on its own
queryUrl, not here —/v1/events/queryrefusesinputs. Use the body its detail'sexamplesshow:
POST https://quicklookup.com/api/v1/services/<serviceGid>/query
Content-Type: application/json
{
"inputs": {"from": "2026-12-20T00:00:00Z", "to": "2027-01-02T00:00:00Z", "country_code": "IS"},
"select": ["gid", "name", "type", "allDay", "dateFrom", "dateTo", "subType", "occurrence"],
"order": "asc",
"limit": 100
}
3. What comes back
Each item is one occurrence:
| field | meaning |
|---|---|
gid, name, type, subType |
identity, title, schema.org type, and the derived sub-type |
dateFrom, dateTo, allDay, timezone |
the interval (half-open, UTC); an all-day event spans its local day |
classification |
facets {type, value, weight} — Category, Subcategory, Genre, Kind, Sport, League, Competition, Season, Round, Format, Audience |
sites |
every place the occurrence takes place: role, label, id + idType (an OpenStreetMap way or node, a provider id), address parts, location, geohash. The first site is the epicenter, which venue and location mirror |
participants |
who is involved: role (AS_HOME_TEAM, ORGANIZER, PERFORMER, BROADCASTER…), entityType, label, id + idType |
media, names |
images and titles by language |
influence |
the demand-driver model: category (accommodation, transport, food, retail, entertainment, general), radiusKm, beforeDays, afterDays, peakOffsetDays, weight, spatialDecay, temporalDecay |
dimensions, metrics, flags, properties |
the feed's own attributes |
countryCode, regions, status, attendanceMode |
ISO 3166-1 alpha-3, the regions, scheduled / cancelled …, in_person / online / hybrid |
distanceMeters, matchedSite |
with near: distance to the nearest site and the 1-based index of the site that matched |
eventSeriesGid |
set when the occurrence belongs to a series (the same happening on several dates) |
4. Everything near a place, across every feed
POST https://quicklookup.com/api/v1/events/search
Content-Type: application/json
{
"near": {"longitude": -21.9, "latitude": 64.13, "radiusKm": 50},
"from": "2026-09-19T00:00:00Z",
"to": "2026-12-18T00:00:00Z",
"order": "distance_asc",
"limit": 200
}
Searches every located feed the token may see; feedsSearched says how many, and
feedsSkipped names any feed whose source could not be read this time (a throttled
provider), so a partial answer is never silent. Page with nextCursor as above.
A search waits about 7.5 s at most for feeds that are still being fetched from their source.
A feed not ready by then is listed in feedsSkipped with retryAfterMs. Its fetch keeps
running, and the same search made after that interval includes its events. A skipped feed
with no retryAfterMs has a source that is unavailable right now. To get the stored feeds
at once and poll for the rest, send Prefer: respond-async (MCP: respondAsync: true).
Those feeds then come back as feedsPending in a 202.
5. Keep a selection
Save the feed, filters and fields you settled on as saved context and
re-run it for any period with query_saved_event_context (MCP) or its REST twin; time and
location are never part of the saved definition, so the same context serves every run.
Mistakes that cost a run
- Polling nothing: a feed that is
pendingdelivery (just published) answers no rows; its detail page says so. - An unregistered field in
fieldsis refused naming it — read the detail page. - A period without
to, ortobeforefrom, is refused; an all-day event must be asked for with a window that covers its local day in UTC. distanceMeterswithoutnearis never returned; distances are to the nearest site.