List merchants

PUBLIC

Returns a paginated list of merchants for the given campaign.

Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…
📘

CacheCache-Control: public, max-age=14400 (4 hours)

Part of the catalog — The product catalog explains how merchants, products, calendars and timeslots fit together.

Why this endpoint exists

A merchant is the venue or operator whose experience you are selling — a zoo, a theme park, a museum, a spa. It is the entity the customer recognises and chooses, and it owns the products they eventually buy.

This is the plain, complete, paginated enumeration of the merchants in your campaign. It is what you build a browse page or a category grid on. When the customer knows what they want and types it, use broad search or custom search instead — this endpoint does not filter.

How to use it

curl "https://api.acc.funtrips.io/v2/merchants?limit=24" \
  -H "x-campaign-id: 3c1e5a90-7b2d-4f61-9a83-1d4e7f2b8c05" \
  -H "Accept-Language: nl-NL"
{
  "data": [
    {
      "id": "8a2f4c61-9d3e-4b57-a0c8-1e5f7b2d9a30",
      "alias": "amsterdam-zoo",
      "title": "Amsterdam Zoo",
      "content": { "…": "descriptions, images" },
      "options": { "…": "merchant flags" },
      "address": { "…": "street, city, coordinates" },
      "categories": [ { "…": "category" } ],
      "tags": ["family", "outdoor"],
      "max_discount": { "…": "deepest discount available" },
      "best_effective_price": { "value": "18.50", "currency": "EUR" },
      "best_list_price": { "value": "24.00", "currency": "EUR" },
      "last_updated": "2026-09-01T08:12:44Z"
    }
  ],
  "meta": {
    "correlation_id": "…",
    "item_count": 24,
    "pagination": { "limit": 24, "next_token": "eyJwayI6…" }
  }
}

Query parameters

ParameterTypeDefaultNotes
limitinteger201–100
next_tokenstringCursor from meta.pagination.next_token

The fields that drive a merchant tile

Most of the payload is content you render as-is. Three fields deserve explanation because they encode pricing decisions, not content.

best_effective_price is the actual price a customer pays for the cheapest discounted product this merchant offers — the "from €18.50" headline on the tile. best_list_price is that same product's pre-discount price, the "was €24.00" strikethrough. They are a pair: render both or neither.

Both are present only when the merchant has at least one discount-eligible product. A merchant with no discounts has no headline price, and your tile needs a sensible layout for that case. Do not fall back to 0 — an absent price means "no promotional price to show", not "free".

max_discount is the deepest discount available across the merchant's products, for a "up to 30% off" badge.

These are computed server-side from stock-aware availability: a product whose remaining days are all sold out does not contribute. That means the headline price you show is one the customer can actually buy, which is the whole point of computing it centrally rather than in your client.

alias is a stable URL-safe slug (amsterdam-zoo). Use it in your own URLs; use id for API calls — including for the merchant detail read.

Ordering

Merchants come back in key order — stable between requests, but not alphabetical, not chronological, and not ranked. If you need a specific order in your UI, sort client-side after collecting the pages, or use custom search, which ranks by relevance and can sort by distance.

Errors

StatustypeCause
500urn:qup:error:merchant-internal-errorUnexpected fault

That is genuinely the only documented failure. A campaign with no merchants returns 200 with an empty data array — not a 404. An unknown x-campaign-id also yields an empty list rather than an error, because the campaign scope is applied as a filter here. If you get an unexpectedly empty catalog, verify your x-campaign-id first — that is the usual cause, and this endpoint will not tell you.

Query Params
integer
1 to 100
Defaults to 20

Number of items to return per page.

string

Opaque pagination cursor returned by a previous response.

Headers
uuid
required

Campaign scope for this request. Filters content to the specified campaign.

string

RFC 7231 language preference. The best match against supported locales (nl-NL, en-GB, de-DE) is selected. Defaults to nl-NL when omitted.

string
enum
Defaults to application/json

Generated from available response content types

Allowed:
Responses

Language
URL
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
application/json
application/problem+json