Admin — list merchants (S2S)

ADMIN

Paginated list of merchants for the caller's campaign. Same payload as
the public GET /merchants, but authenticated server-to-server and
scoped to the campaign the caller's credentials resolve to — no
x-campaign-id header required. Intended for integrators that prefer
to authenticate and cache the catalog on their side.

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

Cache — not cached. Unlike the public catalog endpoints, this response carries no

Cache-Control; cache it on your side if you are polling it.

Why this endpoint exists

The same merchant payload as the public GET /merchants, authenticated
server-to-server instead of by campaign header.

It exists for integrators who would rather hold the catalog on their own side than call the
public endpoints per page view: a nightly crawl into your own search index, a cached catalog behind
your app, or a reconciliation job that needs the merchant list without a browser in the loop.

If your storefront reads the catalog directly, use the public endpoint — it needs no credential at
all and it is cacheable for four hours. This one is for your backend.

Authorisation and scoping

CredentialS2S token (client_credentials)
Scopefuntrips/catalog.read
CampaignResolved from the token's campaign claim

Send no x-campaign-id header. Your credentials already say which campaign you are, and the
response is scoped to it. That is the practical difference from the public endpoint: one fewer
thing to get wrong, and no way to read another campaign's catalog by accident.

Request

curl "https://api.acc.funtrips.io/v2/admin/merchants?limit=100" \
  -H "Authorization: Bearer $S2S_TOKEN" \
  -H "Accept-Language: nl-NL"
ParameterTypeNotes
limitinteger1–100, default 20
next_tokenstringCursor from meta.pagination.next_token
Accept-LanguageheaderChooses the language of translated fields

The response is a paginated array of Merchant objects — identical in shape to
GET /merchants, including the best_effective_price / best_list_price
pair and max_discount. See that page for the field walkthrough.

Crawling it

Page with limit=100 and follow meta.pagination.next_token until it is absent. That is the only
end-of-collection signal — do not stop on a short page.

Merchants come back in key order: stable between requests, but not alphabetical and not
chronological. Sort on your side if your index needs an order.

Crawl once per language you serve. Translated fields follow Accept-Language, so a catalog
cached from a single nl-NL pass will show Dutch text to every customer. One pass per locale in
your campaign's locales.supported.

# one pass per locale
for locale in nl-NL en-GB fr-FR; do
  token=""
  while :; do
    resp=$(curl -s -G "https://api.acc.funtrips.io/v2/admin/merchants" \
      --data-urlencode "limit=100" ${token:+--data-urlencode "next_token=$token"} \
      -H "Authorization: Bearer $S2S_TOKEN" -H "Accept-Language: $locale")
    echo "$resp" | jq -c '.data[]' >> "merchants-$locale.jsonl"
    token=$(echo "$resp" | jq -r '.meta.pagination.next_token // empty')
    [ -z "$token" ] && break
  done
done

Products and calendars have no S2S equivalent

This endpoint covers merchants only. For the rest of the catalog use the public endpoints,
which need no credential — just x-campaign-id:

🚧

Cache metadata, not availability.

Merchant and product detail are safe to hold for hours. The calendar is not — it carries
remaining stock, and a stale copy sells dates that are already gone. Either keep it out of your
index and read it live when the customer opens a date picker, or give it minutes rather than
hours.

Errors

StatusMeaningWhat to do
401S2S token missing, expired or invalidRe-fetch the token, retry once
403Token lacks funtrips/catalog.readProvisioning — contact us
500Server-side faultRetryable

A campaign with no merchants returns 200 with an empty array.

Related

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
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
Credentials
OAuth2
Missing 1 required scope
URL
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
application/json
application/problem+json