Promotion
Promotional offers attached to events: types, discount shapes, validity strategies, per-day-of-week availability, and external references
A Promotion is a special offer attached to a TRCItem (typically an Event). It describes what the offer is (free entry, percentage off, gift), when it's valid (always, in a date range, only as an early-bird, only as a last-minute), and how often it's available (always, or only on specific weekdays).
A single TRCItem may carry several promotions in parallel — e.g. an early-bird discount up to two weeks before, plus a last-minute discount in the final 24 hours, plus a "groups of 10+" gift offer.
Promotion shape
The full set of fields:
| Field | Type | Description |
|---|---|---|
product | string | Internal label for the offer (e.g. "early-bird", "citycard", "1one1"). Human-readable identifier; not shown directly to consumers. |
externalReference | string | Optional pointer to the same offer in your own system. Free-form. Max 255 characters. |
promotionType | enum | none, free, discount, gift, allowance — see PromotionType. |
discount | object | Shape of the price reduction. See Discount. |
enabled | boolean | Master on/off switch. Defaults to true. Setting to false disables the promotion regardless of validity strategy. |
restrictedToRegisteredUsers | boolean | When true, the promotion is only available to logged-in users on partner sites. |
validityStrategy | enum | always, dateRange, earlyBird, lastMinute — see ValidityStrategy. |
startDate | date | Start of the validity window (used by dateRange). |
endDate | date | End of the validity window (used by dateRange). |
eventRelativeDuration | string | ISO 8601 duration relative to the event's start. Used by earlyBird and lastMinute. See Event-relative durations. |
opens | array | Optional per-day-of-week or per-month restriction. Same Open shape as in Calendar. |
translations | array | { lang, description } entries. The description supports simple HTML (<a>, <b>, <i>). |
detailsUrls | array | Optional list of Url objects (see Contactinfo) pointing at terms, the booking page, partner offer details, etc. |
PromotionType
| Value | Meaning |
|---|---|
none | Tracking-only entry — the promotion exists for record-keeping (e.g. an externalReference to a partner system) but represents no active offer. Useful for stitching FeedFactory promotions to upstream systems without implying a discount. |
free | Free entry or free item. Pair with discount.free = true. |
discount | Price reduction. Use discount.percentage (0–100) or discount.amount (absolute, EUR). |
gift | Free gift bundled with the regular ticket. Doesn't reduce the ticket price. |
allowance | Spending allowance or voucher (e.g. "€10 to spend at the bar"). |
Discount
The discount object has three optional fields and the relevant ones are populated based on promotionType:
| Field | Type | Used when |
|---|---|---|
free | boolean | promotionType: "free" — set to true |
percentage | integer | promotionType: "discount" — percentage off (0–100) |
amount | number | promotionType: "discount" — absolute discount in EUR |
For percentage vs amount: pick one. If both are set, partner consumers may render either; behavior is unspecified.
ValidityStrategy
Controls when the promotion is active:
| Value | Active when | Required fields |
|---|---|---|
always (default) | Whenever enabled = true | — |
dateRange | Between startDate and endDate | startDate, endDate |
earlyBird | More than eventRelativeDuration before the event start | eventRelativeDuration |
lastMinute | Within eventRelativeDuration of the event start | eventRelativeDuration |
opens adds a second filter on top of validityStrategy: even if the strategy says "currently active", the promotion is only honoured when today matches one of the opens entries. Useful for offers like "Tuesdays only" or "every first Monday of the month".
Event-relative durations
eventRelativeDuration uses the ISO 8601 duration format.
| Duration | Meaning |
|---|---|
PT1H | 1 hour |
PT24H / P1D | 24 hours / 1 day |
P3D | 3 days |
P2W | 2 weeks |
P1M | 1 month |
P3Y6M4DT12H30M5S | 3 years, 6 months, 4 days, 12 hours, 30 minutes, 5 seconds |
For earlyBird, the duration is read as "the offer is valid up until this much before the event starts". P2W means the offer ends 2 weeks before showtime. For lastMinute, the duration is "the offer kicks in this much before the event starts" — PT24H opens the deal in the final day.
Examples
Free entry on the day of the event
{
"product": "free-day-pass",
"promotionType": "free",
"validityStrategy": "lastMinute",
"eventRelativeDuration": "PT24H",
"discount": { "free": true },
"translations": [
{ "lang": "nl", "description": "Gratis toegang op de dag zelf" },
{ "lang": "en", "description": "Free entry on the day itself" }
]
}Early-bird 20% discount until two weeks before
{
"product": "early-bird-2025",
"promotionType": "discount",
"validityStrategy": "earlyBird",
"eventRelativeDuration": "P2W",
"discount": { "percentage": 20 },
"translations": [
{ "lang": "nl", "description": "20% korting bij vroeg boeken" },
{ "lang": "en", "description": "20% off when booking early" }
]
}Fixed €5 discount during a date range
{
"product": "summer-sale",
"promotionType": "discount",
"validityStrategy": "dateRange",
"startDate": "2026-06-01",
"endDate": "2026-08-31",
"discount": { "amount": 5.0 },
"translations": [
{ "lang": "nl", "description": "Zomerkorting: €5 voordeel" },
{ "lang": "en", "description": "Summer sale: €5 off" }
]
}Tuesday-only gift, registered users only
{
"product": "tuesday-gift",
"promotionType": "gift",
"enabled": true,
"restrictedToRegisteredUsers": true,
"validityStrategy": "always",
"opens": [
{ "day": 3, "whens": [{ "timestart": "00:00", "timeend": "23:59" }] }
],
"translations": [
{ "lang": "nl", "description": "Op dinsdag een gratis drankje (alleen voor leden)" },
{ "lang": "en", "description": "Free drink on Tuesdays (members only)" }
]
}The opens entry uses the same day-of-week numbering as the rest of the API: 1=Sunday, 2=Monday, 3=Tuesday, 4=Wednesday, 5=Thursday, 6=Friday, 7=Saturday.
Partner-system promotion with no FeedFactory-side offer
{
"product": "partner-citycard",
"externalReference": "CITYCARD-CAMPAIGN-2026-Q1",
"promotionType": "none",
"enabled": true,
"validityStrategy": "always"
}promotionType: "none" is the right choice when the entry exists only to point at a partner system (via externalReference) — there's no FeedFactory-side discount to render.
Per-event vs. account-level templates
Promotions on a TRCItem are instance-level — they apply to that single event/location/venue/route. There are also account-level promotion templates (configured under Account → Promotions in the console) that fan out automatically across an account's events, locations, or venues based on matching rules.
The externalReference field is not propagated by template-based cloning: clones start with externalReference = null. If you need an external pointer, set it on the per-event promotion after the clone.
External reference
externalReference is a free-form string (max 255 characters) that connects this promotion to its counterpart in another system — a partner site's "actie" record, a CRM coupon code, a ticketing-platform promotion ID. Event Connectors does not validate or interpret the value; it round-trips as-is on every read and write.
Use it to avoid inventing marker conventions or out-of-band spreadsheets to track which FeedFactory promotion corresponds to which partner record.
Translations
Each promotion carries a translations array of { lang, description } objects. The description is the user-facing text consumers render (in the matching language) — it supports simple HTML elements like <a>, <b>, <i>. Plain \n is not rendered as a line break; wrap content in HTML if you need formatting.
{
"translations": [
{ "lang": "nl", "description": "20% korting <b>tot 1 mei</b>" },
{ "lang": "en", "description": "20% off <b>until 1 May</b>" }
]
}Details URLs
Optional links to more information about the promotion — terms, booking flows, partner offer pages. Each entry is a Url with an optional urlServiceType (general, booking, webshop, etc.) and per-language description translations.
{
"detailsUrls": [
{
"url": "https://partner.example.com/offers/early-bird",
"urlServiceType": "booking",
"descriptionTranslations": [
{ "lang": "nl", "label": "Boek met early-bird tarief" },
{ "lang": "en", "label": "Book at early-bird rate" }
]
}
]
}Notes
- The
productfield is not shown directly to consumers — it's an internal identifier. Rendertranslations[lang].descriptioninstead. - An
enabled: falsepromotion is suppressed everywhere, even if itsvalidityStrategywould otherwise mark it active. Use this as a quick kill-switch. - A promotion with no
validityStrategydefaults toalways. - A promotion with
validityStrategy: "dateRange"but missingstartDateorendDateis treated as inactive.
See the API Reference for the full Promotion schema.