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.
| Time | Status | User Agent | |
|---|---|---|---|
Retrieving recent requests… | |||
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
| Credential | S2S token (client_credentials) |
| Scope | funtrips/catalog.read |
| Campaign | Resolved 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"| Parameter | Type | Notes |
|---|---|---|
limit | integer | 1–100, default 20 |
next_token | string | Cursor from meta.pagination.next_token |
Accept-Language | header | Chooses 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
doneProducts 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:
GET /merchants/{id}/productsGET /merchants/{id}/products/{uuid}GET /merchants/{id}/products/{uuid}/calendar
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
| Status | Meaning | What to do |
|---|---|---|
401 | S2S token missing, expired or invalid | Re-fetch the token, retry once |
403 | Token lacks funtrips/catalog.read | Provisioning — contact us |
500 | Server-side fault | Retryable |
A campaign with no merchants returns 200 with an empty array.
Related
- The product catalog — the model, and which endpoint answers what
GET /merchants— the public equivalent- Pagination
