PUBLIC
Returns the render-relevant configuration of the campaign identified
by the x-campaign-id header: which discount experience to render,
what wallet tokens represent, and which languages to offer. Intended
to be fetched once at storefront boot; responses may be cached.
| 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
Your storefront has to make several decisions before it can render anything, and all of them depend on how your campaign is configured: does this campaign discount through a loyalty wallet, a club membership, or vouchers? Is a wallet token worth a cent or a point? What does a date change cost? Which languages should the language switcher offer?
Hardcoding any of that in your front-end means a configuration change on our side silently desynchronises your UI — the classic symptom being a storefront that shows a voucher field for a campaign that switched to loyalty. This endpoint is the single source of truth, so you read it instead of assuming.
How to use it
Call it once when the storefront boots, cache the result for the session, and drive your rendering off it. It is public and cacheable — no token needed, safe to call from the browser.
curl https://api.acc.funtrips.io/v2/campaign/config \
-H "x-campaign-id: 3c1e5a90-7b2d-4f61-9a83-1d4e7f2b8c05"{
"data": {
"discount_type": "LOYALTY",
"currency": "EUR",
"token_unit": "cents",
"date_change_cost": { "value": "2.50", "currency": "EUR" },
"booking_cost_per_ticket": { "value": "0.99", "currency": "EUR" },
"flexible_date_cost_per_ticket": { "value": "1.50", "currency": "EUR" },
"locales": {
"default": "nl-NL",
"supported": ["nl-NL", "en-GB", "fr-FR"]
}
},
"meta": { "correlation_id": "…" }
}Response fields
| Field | Type | Meaning |
|---|---|---|
discount_type | string, nullable | LOYALTY, CLUB_MEMBERSHIP or VOUCHER. null when the campaign has no discount mechanism. This decides which discount UI you render. |
currency | string, nullable | ISO 4217 code for the campaign. |
token_unit | string, nullable | What one wallet token represents — cents or points. null when there is no wallet. |
date_change_cost | money, nullable | Fixed fee per order to change a visit date. Waived for orders bought with the flexible-date option. |
booking_cost_per_ticket | money, nullable | Surcharge per ticket. 0 is a valid, meaningful value. |
flexible_date_cost_per_ticket | money, nullable | Surcharge per ticket for the flexible-date option. |
locales.default | string | BCP 47 tag used when Accept-Language is absent. |
locales.supported | string[] | Tags to offer in your language switcher. |
token_unit changes what a balance means
token_unit changes what a balance meansA wallet balance of 1250 is €12.50 when token_unit is cents and 1250 points when it is points. There is no unit on the balance itself — GET /me/loyalty/ledger/balance returns a bare integer. Read the unit from here and format accordingly. Getting this wrong renders a €12.50 balance as "1250 points", or worse, the reverse.
Per-ticket versus per-order
booking_cost_per_ticket and flexible_date_cost_per_ticket are multiplied by the ticket count; date_change_cost is a flat per-order fee. This asymmetry is real and it is a common source of client-side total mismatches.
You do not need to compute any of it: create checkout returns authoritative totals. Use these values for previews — "+ €0.99 booking fee per ticket" next to a product — and always render the server's totals at the review step.
Errors
| Status | type | Cause |
|---|---|---|
400 | — | x-campaign-id missing or not a UUID |
404 | urn:qup:error:campaign-not-found | No campaign with that id, or it is not configured |
500 | — | Unexpected fault |
A 404 here means your campaign id is wrong or the campaign has not been provisioned. On a fresh integration it is almost always the former; if you are sure the id is right, tell us — an unprovisioned campaign is something only we can fix.
