Guide: Reading from GET Β· Conditions β
GET /discounts response
OpenAPI reference: GET https://streaming.loyal.guru/discounts.
Typical use cases for integrations:
- Campaign catalog for the customer (filter
customer_idorcustomer_code). - Campaigns available by country or store (
countries,location_id,location_code).
List behavior:
- Returns only active campaigns (
active: true) that are valid peravailable_from/available_to. - Order in
data[]: mass β loyalty β targeted. - For targeted, excludes cancelled vouchers or those with no redemptions left.
- The same campaign may appear multiple times for a customer if sent in several deliveries; for a specific delivery use
GET /discounts/{value}withsearch_by=campaign_history_id(see API docs).
On this pageβ
- Query parameters
- Response wrapper
- Rule fields in the response
- Metadata per item in
data[] coupon_info(whencoupon_required: true)voucher_info(onlyselect_customers: targeted)- POS helper fields
- LG calculation mode (reference)
Query parametersβ
| Parameter | Usage |
|---|---|
campaign_audience | all_customers, loyalty, or targeted. No value: returns all three types (subject to other filters). |
customer_id / customer_code | Mutually exclusive. Customer catalog: mass + loyalty for registration country + targeted for that customer. |
countries | Mass/loyalty by country (ES, ES&countries=FR = ES or FR). Mutually exclusive with location_id / location_code. |
location_id / location_code | Campaigns at that store. If you send both, only location_id applies. |
tier_id | Campaigns for the tier (mass + loyalty). Mutually exclusive with customer_id / customer_code. |
category_id | Filter by campaign category. |
selected | Only with customer + location: true = selected targeted vouchers; false = not selected. No value: all. For targeted only, also use campaign_audience=targeted. |
starting_after | Pagination: value of next_token_starts_after from the previous page. |
Response wrapperβ
| Field | Description |
|---|---|
data | Array of campaign objects. |
next_token_starts_after | Token for the next page (starting_after). Absent on the last page. |
Rule fields in the responseβ
GET /discounts (list) and GET /discounts/{id} (detail) use the same names on the campaign object:
| Response field | Typical type | Content after parsing |
|---|---|---|
rule_conditions | string JSON | Object with conditions.and[] / conditions.or[] |
rule_application | string JSON | Object with application.and[] (internal key application, not conditions) |
rule_effects | string JSON | Effect: type, value, distribution, limits, rule_group, β¦ |
Victory frequency and budget: once, once_limit, budget_value, budget_period, maximum_discount_transaction β see Limits.
Internal structure vs field name: the API field is
rule_application, but inside parsed JSON the root is usuallyapplication.and[]. Do not confuse the response field name with the object's internal key.
Metadata per item in data[]β
Besides JSON rules, each campaign includes:
| Block | Fields | Integration use |
|---|---|---|
| Identity | id, name, description | Campaign ID and catalog / UI copy. |
| Category | category.id, category.name, category.priority | Evaluation group and stackability β Stackability. |
| Validity | active, available_from, available_to, recurrence_type, recurrence_days | Whether the campaign applies today; recurrence_type: weekly uses recurrence_days (weekdays). |
| Event / currency | when, currency | Cart: after_create_activity; campaign currency. |
| Audience | select_customers, customer_registration_countries, tiers[], coupon_required | all_customers (mass), loyalty (club), targeted (targeted audience). coupon_required: true means coupon at checkout. In list: tiers[]; detail may include achievement_definitions. |
| Coupon | coupon_info (if coupon_required: true) | Campaign coupon configuration. Does not include voucher data except for targeted campaigns. |
| Limits | once, once_limit, budget_value, budget_period, maximum_discount_transaction | Victory frequency and budget β Limits. once: always, num_day, num_month, num_year, num_total. |
| Stackability | stackability_properties, priority | stackability or highest_discount within the category; priority orders within the group. |
| Partner | partner (optional) | id, name, description, image_url for co-branding in catalog. |
| POS integration | product_ids_rule_conditions, product_ids_rule_application, locations_ids, location_codes (optional) | Coupon server mode + internal taxonomy β see POS helper fields. |
coupon_info (when coupon_required: true)β
If the campaign has coupon_required: true, the response always includes the coupon_info object (coupon configuration: IDs, name, shared static code if applicable, etc.). This applies to mass and loyalty campaigns with optional/required coupon in configuration, not only targeted.
| Field | Description |
|---|---|
coupon_info.coupon_id | Campaign coupon ID. |
coupon_info.static_code | Static coupon code (mass/loyalty campaigns with shared code). |
coupon_info.coupon_name | Coupon name. |
coupon_info.external_id | External reference ID. |
coupon_info.key | Internal platform key. |
For mass/loyalty with a static coupon, static_code (or the agreed code) in coupons_desired on POST /carts is usually enough. coupon_info does not include voucher_info in those cases.
voucher_info (only select_customers: targeted)β
The coupon_info.voucher_info subobject appears only when select_customers is targeted: the campaign is tied to a voucher (unique code per customer) issued in a targeted delivery. You need voucher detail for catalog, in-store selection, and redemption.
| Field | Description |
|---|---|
coupon_info.voucher_info.voucher_id | Customer voucher ID. |
coupon_info.voucher_info.voucher_code | Unique code to present at checkout / API. |
coupon_info.voucher_info.available_redemptions | Remaining redemptions. |
coupon_info.voucher_info.max_redemptions | Maximum redemptions. |
coupon_info.voucher_info.selected | Whether the voucher is selected for the customer at that store (requires customer + location filters on GET). |
coupon_info.voucher_info.status | Voucher status (e.g. pending). |
coupon_info.voucher_info.available_from / available_to | Redemption window. |
coupon_info.voucher_info.print_from / print_to | Print window (if applicable). |
coupon_info.voucher_info.printable | Whether it can be printed. |
coupon_info.voucher_info.priority | Voucher priority in selection. |
coupon_required: true β coupon_info (always)
select_customers: targeted β coupon_info.voucher_info (additionally)
For targeted checkout, send voucher_code (or the relevant code) in coupons_desired. See Campaigns API.
POS helper fieldsβ
These four fields may appear on GET /discounts and GET /discounts/{id} only when the Company is a coupon server: configurations.default_apply_discounts is false. If that slug is missing or true, Loyal Guru is the promo engine and these arrays are not returned β parse rule_* instead.
In coupon server mode Loyal Guru does not calculate or apply the discount amount on the cart; it validates coupons/vouchers and the POS or retailer system applies the promotion at checkout.
configurations.default_apply_discounts (Company) | Loyal Guru role on the cart | Fields in GET response |
|---|---|---|
false | Coupon server only (code redemption/validation) | May include product_ids_rule_* and locations_* / location_codes (see population below) |
true (default) | LG calculates discounts via engine (POST /carts, apply_discounts in payload) | Those arrays are not returned; use rule_conditions, rule_application, rule_effects |
Do not confuse two levels:
configurations.default_apply_discounts(Company) defines whether GET can include POS arrays. EachPOST /cartspayloadapply_discountscontrols whether that transaction evaluates discounts in LG β see Discounts overview.
When the company switch is false, Loyal Guru still decides per campaign whether to populate each array (internal taxonomy vs direct IDs/codes, victory vs application, store categories vs store ID/code). Empty arrays are valid.
When arrays are populated (internal taxonomy)β
Loyal Guru expands to flat lists only for categories linked to an internal taxonomy (catalog maintained in LG). Coupon server mode alone is not enough: arrays carry useful IDs/codes only if the campaign scopes by categories resolvable on the platform.
| Array | Populated when⦠|
|---|---|
product_ids_rule_conditions | rule_conditions has field: product_categories (usually array_field: lines) with values (feature_pk) from internal product taxonomy. See feature_pk format. |
product_ids_rule_application | rule_application has product_categories with internal taxonomy (effect scope). |
locations_ids, location_codes | rule_conditions has field: location_categories with internal store category taxonomy. See Catalog β store. |
If the rule uses only direct product_id / location_id, or categories with external taxonomy without mapping in LG, arrays are usually empty: the POS must parse rule_* or its own catalog.
Field tableβ
| Field | Type (API) | Interpretation |
|---|---|---|
product_ids_rule_conditions | string[] | Products from victory conditions, expanded from product_categories with internal taxonomy. Empty if not applicable. See Products on lines. |
product_ids_rule_application | string[] | Products from effect scope, expanded from product_categories with internal taxonomy in rule_application. |
locations_ids | integer[] | Stores expanded from location_categories with internal taxonomy. |
location_codes | string[] | External codes for those stores. |
Notes for POS integrationsβ
- Empty is expected if there are no resolvable internal categories or the campaign does not scope by product/store in that block.
- They do not replace
rule_*: they coexist in coupon server mode; use arrays when populated. - If you do not see these fields,
configurations.default_apply_discountsistruefor the Company (LG engine active).
LG calculation mode (reference)β
With configurations.default_apply_discounts = true, the usual flow is to parse rule_* and send the cart to POST /carts with apply_discounts: true to get calculated effects[]. See Campaigns API.
Parsing:
rule_conditions,rule_application, andrule_effectsusually arrive as JSON strings. Deserialize before reading clauses. Inrule_effects, the valid bundle field isrule_group(not legacy variants such asrule_groupedin old samples).