PUBLIC
Returns merchants using field-boosted search with optional geo-distance filtering.
Either query or all three geo params (lat, lon, distance) must be provided.
When both are provided, results must match the query text AND be within the specified distance.
When limit is provided the response is paginated and meta.pagination is included.
Without limit, all matching results are returned.
| Time | Status | User Agent | |
|---|---|---|---|
Retrieving recent requests… | |||
Cache —Cache-Control: public, max-age=3600(1 hour)
Part of the catalog — The product catalog explains how merchants, products, calendars and timeslots fit together.
Why this endpoint exists
Two jobs that broad search cannot do:
Field-boosted text matching. A hit on the merchant's name ranks above a hit in its description, so "Zoo" puts Amsterdam Zoo first instead of every merchant whose blurb mentions animals. If broad search returns technically-correct but badly-ordered results, this is the fix.
"Near me". Filter to merchants within a radius of a coordinate and get the distance back on each result, so you can build a map view or a "closest first" list.
Parameter combinations
This endpoint has a required-parameter rule that is easy to get wrong: you must supply either query, or all three of lat, lon and distance. The geo trio is all-or-nothing.
| Sent | Behaviour |
|---|---|
query only | Field-boosted text search across the campaign |
lat + lon + distance | Every merchant within the radius, no text filter |
query + all three geo params | AND — must match the text and be inside the radius |
| Neither / partial geo | 400 |
The combined mode is the one to reach for on a "search near me" UI. Note it is a conjunction: a strong text match 50 km outside the radius is excluded entirely, not ranked lower.
How to use it
# Text search, name-boosted
curl "https://api.acc.funtrips.io/v2/merchants/search?query=zoo&limit=20" \
-H "x-campaign-id: $CAMPAIGN_ID"
# Within 25 km of Amsterdam Centraal
curl "https://api.acc.funtrips.io/v2/merchants/search?lat=52.3791&lon=4.9003&distance=25000&limit=20" \
-H "x-campaign-id: $CAMPAIGN_ID"
# Both
curl "https://api.acc.funtrips.io/v2/merchants/search?query=zoo&lat=52.3791&lon=4.9003&distance=25000&limit=20" \
-H "x-campaign-id: $CAMPAIGN_ID"Query parameters
| Parameter | Type | Required | Notes |
|---|---|---|---|
query | string | Conditional | Required unless all geo params are given |
lat | double | Conditional | Latitude. Required with lon + distance |
lon | double | Conditional | Longitude. Required with lat + distance |
distance | integer | Conditional | Radius in metres — 25000, not 25 |
limit | integer | No | 1–100. Omitting it returns all matches unpaginated |
next_token | string | No | Cursor |
distanceis in metresPassing
25gives you a 25-metre radius and an empty result set that looks like a data problem. This is the single most common mistake on this endpoint.
distance_meters on the response
distance_meters on the responseWhen you supply coordinates, each merchant carries an extra field:
{
"id": "8a2f4c61-9d3e-4b57-a0c8-1e5f7b2d9a30",
"title": "Amsterdam Zoo",
"distance_meters": 1840,
"…": "the usual Merchant fields"
}It is straight-line distance, not travel distance — good for sorting and for "1.8 km away", wrong for "8 minutes by car". The field is absent entirely when no coordinates were sent, so do not depend on its presence.
Everything else matches the Merchant shape from list merchants, including the best_effective_price / best_list_price pair.
Errors
| Status | type | Cause |
|---|---|---|
400 | — | Neither query nor a complete geo trio; or a malformed coordinate |
502 | urn:qup:error:merchant-search-failed | Search backend failed |
504 | urn:qup:error:merchant-search-timed-out | Search backend timed out |
500 | urn:qup:error:merchant-internal-error | Unexpected fault |
As with broad search, always send limit — an unbounded search is the usual cause of a 504. No matches is 200 with an empty array.
