Pre-launch API. The concepts described here are settled, but the API shape is not: request and response fields, parameters and defaults can still change. Build against it, and talk to your Luigi's Box contact before you put an integration into production.
const url = 'https://api.eu1.luigisbox.ai/platform/v1/campaigns/example?filter_syntax=group';const options = { method: 'PATCH', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"catalog_ids":["example"],"catalog_tags":["example"],"channel_ids":["example"],"channel_tags":["example"],"disclosure":{"advertiser":"example","payer":"example","type":"sponsored"},"ends_at":"2026-04-15T12:00:00Z","intents":["search"],"match":{"$and":[{"brand":{"in":["nike","adidas"]}},{"lbx:price":{"gte":50,"lte":200}},{"$or":[{"condition":{"eq":"new"}},{"warranty_months":{"gte":12}}]},{"$not":{"material":{"eq":"leather"}}},{"image":{"exists":true}}]},"name":"example","rules":[{"effect":{"decay_window":"example","mode":"hard","position":1,"respect_user_filters":false,"type":"pin"},"id":"example","name":"example","record_match":{"$and":[{"brand":{"in":["nike","adidas"]}},{"lbx:price":{"gte":50,"lte":200}},{"$or":[{"condition":{"eq":"new"}},{"warranty_months":{"gte":12}}]},{"$not":{"material":{"eq":"leather"}}},{"image":{"exists":true}}]}}],"starts_at":"2026-04-15T12:00:00Z","status":"draft","surface_ids":["example"],"surface_tags":["example"],"timezone":"example"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request PATCH \ --url 'https://api.eu1.luigisbox.ai/platform/v1/campaigns/example?filter_syntax=group' \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "catalog_ids": [ "example" ], "catalog_tags": [ "example" ], "channel_ids": [ "example" ], "channel_tags": [ "example" ], "disclosure": { "advertiser": "example", "payer": "example", "type": "sponsored" }, "ends_at": "2026-04-15T12:00:00Z", "intents": [ "search" ], "match": { "$and": [ { "brand": { "in": [ "nike", "adidas" ] } }, { "lbx:price": { "gte": 50, "lte": 200 } }, { "$or": [ { "condition": { "eq": "new" } }, { "warranty_months": { "gte": 12 } } ] }, { "$not": { "material": { "eq": "leather" } } }, { "image": { "exists": true } } ] }, "name": "example", "rules": [ { "effect": { "decay_window": "example", "mode": "hard", "position": 1, "respect_user_filters": false, "type": "pin" }, "id": "example", "name": "example", "record_match": { "$and": [ { "brand": { "in": [ "nike", "adidas" ] } }, { "lbx:price": { "gte": 50, "lte": 200 } }, { "$or": [ { "condition": { "eq": "new" } }, { "warranty_months": { "gte": 12 } } ] }, { "$not": { "material": { "eq": "leather" } } }, { "image": { "exists": true } } ] } } ], "starts_at": "2026-04-15T12:00:00Z", "status": "draft", "surface_ids": [ "example" ], "surface_tags": [ "example" ], "timezone": "example" }'Partial update. An archived campaign is terminal: every update is rejected with 409, including a status change, so it can never be un-archived — create a new campaign instead. A present rules list fully replaces the rule set. Filter trees are normalised before they are stored — a negative leaf gains an exists on its field beside it (see match and record_match) — so the resource this returns can differ from the body sent. The response carries the stored form.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters ”Query Parameters
Section titled “Query Parameters ”Syntax filter trees are rendered in. group is the {operator, conditions} form; map is the $and / $or / $not map syntax the Discovery API uses, in which an empty tree renders as null. Request bodies accept either syntax regardless of this setting.
Syntax filter trees are rendered in. group is the {operator, conditions} form; map is the $and / $or / $not map syntax the Discovery API uses, in which an empty tree renders as null. Request bodies accept either syntax regardless of this setting.
Request Body required
Section titled “Request Body required ”Partial update (JSON Merge Patch). Only fields present in the request are applied.
A present rules list fully replaces the campaign’s rule set, within the bounds
published on the field (a campaign is never left ruleless). Rules carrying an id
keep that id (and their analytics history); id-less rules are created new.
The list’s order is the campaign’s rule order and is stored as sent: re-sending the same rules in a different order is how a campaign is re-ordered, and that order is what breaks a tie between two rules of one campaign when they compete for the same product.
object
Catalogs this campaign narrows to, by id. catalog_tags narrows the same axis by contributing its members, so the scope is the union of the two. An axis nothing narrows is an axis the campaign does not restrict, so empty means every one of them rather than none. A catalog outside the organization is rejected with catalog_not_in_organization.
Catalog tags whose members join catalog_ids on the catalog axis. Resolved at read time, so editing a tag reflows into every campaign referencing it. A tag that does not exist in the organization is rejected with tag_not_found, and one carrying another dimension with tag_dimension_mismatch.
Channels this campaign narrows to, by id, jointly with channel_tags. An axis nothing narrows is an axis the campaign does not restrict, so empty means every one of them rather than none. Narrowing by channel requires a catalog scope (catalog_scope_required), the channel must be in the organization (channel_not_in_organization) and owned by a scoped catalog (channel_outside_catalog_scope).
Channel tags whose members join channel_ids on the channel axis, under the same resolution and the same tag_not_found / tag_dimension_mismatch rejections.
How this campaign’s placements are disclosed to shoppers.
Every product the campaign’s rules pin or boost carries it as the served hit’s
@disclosure object, together with the recipient_parameters derived from the
campaign; a boosted product’s also name the request’s own context.
object
The person or company on whose behalf the placement is shown, e.g. Northwear Ltd. At most 128 characters. A control character, invisible mark or bidirectional override is rejected with the validation error type disclosure_name_unprintable.
Who paid for the placement. Rejected with the validation error type disclosure_payer_requires_advertiser without an advertiser. At most 128 characters.
How the placement is disclosed. sponsored declares a paid placement.
Surface Intents this campaign targets — the kind of discovery it applies to. Empty means every Intent, not none. Narrowing by Intent is mutually exclusive with narrowing by surface_ids / surface_tags: an Intent targets whole families of surfaces, so combining the two is rejected with intents_conflict. A targeted Intent no scoped catalog hosts a surface for is rejected with catalog_without_targeted_intent — it could never trigger.
A filter tree in group syntax: a boolean operator over leaves and nested groups.
not holds exactly one child. An empty and constrains nothing and an
empty or matches nothing; each endpoint says whether it accepts either.
object
Leaf conditions and nested groups.
One leaf of a group-syntax tree: a field compared against a value.
object
Object field the condition reads.
What a condition reading its value from the request’s anchors does when none carries the attribute.
fail_closed (the default) makes the whole filter tree match nothing. ignore
drops the condition instead, leaving the rest of the tree in force.
Comparison operator.
Provenance of the condition; stamped by the system, never read from a client.
Literal to compare against, or a trigger reference {trigger_ref: ...}; a scalar for eq/neq and the comparisons, a non-empty list for in/not_in, absent for exists.
Where a dynamic condition reads its value: an attribute of the request’s anchors.
object
Anchor attribute whose value the condition compares against.
Boolean combinator applied to conditions.
A group node: exactly one of $and, $or, $not.
object
Nodes that must all match.
A condition node: field names mapped to operator objects; sibling fields combine as AND.
object
Operators applied to one field. Several operators in one object combine as AND.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A condition node: field names mapped to operator objects; sibling fields combine as AND.
object
Operators applied to one field. Several operators in one object combine as AND.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
Nodes of which at least one must match.
A condition node: field names mapped to operator objects; sibling fields combine as AND.
object
Operators applied to one field. Several operators in one object combine as AND.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A condition node: field names mapped to operator objects; sibling fields combine as AND.
object
Operators applied to one field. Several operators in one object combine as AND.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A rule in an update payload. An id echoed back from a prior response marks an
existing rule to keep — its fields are updated in place and its rule_id (which
analytics attribution aggregates on) is preserved. Omit id to create a new rule;
existing rules absent from the list are dropped.
object
Pin the selected product to a fixed 1-indexed position.
mode='soft' is the Soft Pin: the placement decays over decay_window.
respect_user_filters is live: an id-naming pin carrying False — the default
— has its product exempted from the shopper’s own post-filter.
Exclude the selected product(s) from results entirely.
object
Raise matching products in the ranking. strength_pct (0–1) scales how far.
A filter tree in group syntax: a boolean operator over leaves and nested groups.
not holds exactly one child. An empty and constrains nothing and an
empty or matches nothing; each endpoint says whether it accepts either.
object
Leaf conditions and nested groups.
One leaf of a group-syntax tree: a field compared against a value.
object
Object field the condition reads.
What a condition reading its value from the request’s anchors does when none carries the attribute.
fail_closed (the default) makes the whole filter tree match nothing. ignore
drops the condition instead, leaving the rest of the tree in force.
Comparison operator.
Provenance of the condition; stamped by the system, never read from a client.
Literal to compare against, or a trigger reference {trigger_ref: ...}; a scalar for eq/neq and the comparisons, a non-empty list for in/not_in, absent for exists.
Where a dynamic condition reads its value: an attribute of the request’s anchors.
object
Anchor attribute whose value the condition compares against.
Boolean combinator applied to conditions.
A group node: exactly one of $and, $or, $not.
object
Nodes that must all match.
A condition node: field names mapped to operator objects; sibling fields combine as AND.
object
Operators applied to one field. Several operators in one object combine as AND.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A condition node: field names mapped to operator objects; sibling fields combine as AND.
object
Operators applied to one field. Several operators in one object combine as AND.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
Nodes of which at least one must match.
A condition node: field names mapped to operator objects; sibling fields combine as AND.
object
Operators applied to one field. Several operators in one object combine as AND.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A condition node: field names mapped to operator objects; sibling fields combine as AND.
object
Operators applied to one field. Several operators in one object combine as AND.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
Lifecycle state of a Campaign.
Surfaces this campaign narrows to, by id, jointly with surface_tags. An axis nothing narrows is an axis the campaign does not restrict, so empty means every one of them rather than none. Mutually exclusive with intents (intents_conflict), requires a catalog scope (catalog_scope_required), and each surface must sit under a scoped catalog (surface_not_in_catalog_scope).
Surface tags whose members join surface_ids on the surface axis, under the same resolution and rejections. A member whose own catalog is outside the catalog scope is tolerated rather than rejected, which keeps a surface tag reusable across catalogs.
Responses
Section titled “ Responses ”Successful Response
Campaign response: the explicit picks the merchandiser made, round-trippable into an update.
The effective scope — those picks unioned with the current members of the picked tags —
is not here; read it from
GET /platform/v1/campaigns/{campaign_id}/effective-scope. See CampaignEffectiveScope.
object
Catalogs this campaign narrows to, by id. catalog_tags narrows the same axis by contributing its members, so the scope is the union of the two. An axis nothing narrows is an axis the campaign does not restrict, so empty means every one of them rather than none. A catalog outside the organization is rejected with catalog_not_in_organization.
Catalog tags whose members join catalog_ids on the catalog axis. Resolved at read time, so editing a tag reflows into every campaign referencing it. A tag that does not exist in the organization is rejected with tag_not_found, and one carrying another dimension with tag_dimension_mismatch.
Channels this campaign narrows to, by id, jointly with channel_tags. An axis nothing narrows is an axis the campaign does not restrict, so empty means every one of them rather than none. Narrowing by channel requires a catalog scope (catalog_scope_required), the channel must be in the organization (channel_not_in_organization) and owned by a scoped catalog (channel_outside_catalog_scope).
Channel tags whose members join channel_ids on the channel axis, under the same resolution and the same tag_not_found / tag_dimension_mismatch rejections.
How this campaign’s placements are disclosed to shoppers.
Every product the campaign’s rules pin or boost carries it as the served hit’s
@disclosure object, together with the recipient_parameters derived from the
campaign; a boosted product’s also name the request’s own context.
object
The person or company on whose behalf the placement is shown, e.g. Northwear Ltd. At most 128 characters. A control character, invisible mark or bidirectional override is rejected with the validation error type disclosure_name_unprintable.
Who paid for the placement. Rejected with the validation error type disclosure_payer_requires_advertiser without an advertiser. At most 128 characters.
How the placement is disclosed. sponsored declares a paid placement.
Surface Intents this campaign targets — the kind of discovery it applies to. Empty means every Intent, not none. Narrowing by Intent is mutually exclusive with narrowing by surface_ids / surface_tags: an Intent targets whole families of surfaces, so combining the two is rejected with intents_conflict. A targeted Intent no scoped catalog hosts a surface for is rejected with catalog_without_targeted_intent — it could never trigger.
A filter tree in group syntax: a boolean operator over leaves and nested groups.
not holds exactly one child. An empty and constrains nothing and an
empty or matches nothing; each endpoint says whether it accepts either.
object
Leaf conditions and nested groups.
One leaf of a group-syntax tree: a field compared against a value.
object
Object field the condition reads.
What a condition reading its value from the request’s anchors does when none carries the attribute.
fail_closed (the default) makes the whole filter tree match nothing. ignore
drops the condition instead, leaving the rest of the tree in force.
Comparison operator.
Provenance of the condition; stamped by the system, never read from a client.
Literal to compare against, or a trigger reference {trigger_ref: ...}; a scalar for eq/neq and the comparisons, a non-empty list for in/not_in, absent for exists.
Where a dynamic condition reads its value: an attribute of the request’s anchors.
object
Anchor attribute whose value the condition compares against.
Boolean combinator applied to conditions.
A group node: exactly one of $and, $or, $not.
object
Nodes that must all match.
A condition node: field names mapped to operator objects; sibling fields combine as AND.
object
Operators applied to one field. Several operators in one object combine as AND.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A condition node: field names mapped to operator objects; sibling fields combine as AND.
object
Operators applied to one field. Several operators in one object combine as AND.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
Nodes of which at least one must match.
A condition node: field names mapped to operator objects; sibling fields combine as AND.
object
Operators applied to one field. Several operators in one object combine as AND.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A condition node: field names mapped to operator objects; sibling fields combine as AND.
object
Operators applied to one field. Several operators in one object combine as AND.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
The array’s order is the campaign’s rule order and is stored as sent. Between two rules of one campaign competing for the same product, the one listed first wins, so re-sending the same rules in a different order re-orders the campaign.
object
Pin the selected product to a fixed 1-indexed position.
mode='soft' is the Soft Pin: the placement decays over decay_window.
respect_user_filters is live: an id-naming pin carrying False — the default
— has its product exempted from the shopper’s own post-filter.
Exclude the selected product(s) from results entirely.
object
Raise matching products in the ranking. strength_pct (0–1) scales how far.
A filter tree in group syntax: a boolean operator over leaves and nested groups.
not holds exactly one child. An empty and constrains nothing and an
empty or matches nothing; each endpoint says whether it accepts either.
object
Leaf conditions and nested groups.
One leaf of a group-syntax tree: a field compared against a value.
object
Object field the condition reads.
What a condition reading its value from the request’s anchors does when none carries the attribute.
fail_closed (the default) makes the whole filter tree match nothing. ignore
drops the condition instead, leaving the rest of the tree in force.
Comparison operator.
Provenance of the condition; stamped by the system, never read from a client.
Literal to compare against, or a trigger reference {trigger_ref: ...}; a scalar for eq/neq and the comparisons, a non-empty list for in/not_in, absent for exists.
Where a dynamic condition reads its value: an attribute of the request’s anchors.
object
Anchor attribute whose value the condition compares against.
Boolean combinator applied to conditions.
A group node: exactly one of $and, $or, $not.
object
Nodes that must all match.
A condition node: field names mapped to operator objects; sibling fields combine as AND.
object
Operators applied to one field. Several operators in one object combine as AND.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A condition node: field names mapped to operator objects; sibling fields combine as AND.
object
Operators applied to one field. Several operators in one object combine as AND.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
Nodes of which at least one must match.
A condition node: field names mapped to operator objects; sibling fields combine as AND.
object
Operators applied to one field. Several operators in one object combine as AND.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A condition node: field names mapped to operator objects; sibling fields combine as AND.
object
Operators applied to one field. Several operators in one object combine as AND.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
A value resolved from the request’s trigger attributes at evaluation time.
object
Lifecycle state of a Campaign.
Surfaces this campaign narrows to, by id, jointly with surface_tags. An axis nothing narrows is an axis the campaign does not restrict, so empty means every one of them rather than none. Mutually exclusive with intents (intents_conflict), requires a catalog scope (catalog_scope_required), and each surface must sit under a scoped catalog (surface_not_in_catalog_scope).
Surface tags whose members join surface_ids on the surface axis, under the same resolution and rejections. A member whose own catalog is outside the catalog scope is tolerated rather than rejected, which keeps a surface tag reusable across catalogs.
IANA timezone identifier (e.g. Europe/Bratislava) the schedule was authored in, kept so it can be re-opened in that zone. Informational only: starts_at / ends_at are the UTC instants that govern when the campaign runs, and this field never shifts them — use it when re-planning a schedule, never to compute execution times. Requires at least one of starts_at / ends_at, and is cleared when both are cleared. Because tz databases differ between releases and between server and browser (Europe/Kiev vs Europe/Kyiv), a client whose own database does not know the identifier should keep the string as it is rather than discard or rewrite it. A scheduled campaign always reads back a zone — UTC when none was authored; an unscheduled one omits the field, so a response never shows the zone-without-schedule state that writes reject.
Example
{ "disclosure": { "type": "sponsored" }, "intents": [ "search" ], "match": { "$and": [ { "brand": { "in": [ "nike", "adidas" ] } }, { "lbx:price": { "gte": 50, "lte": 200 } }, { "$or": [ { "condition": { "eq": "new" } }, { "warranty_months": { "gte": 12 } } ] }, { "$not": { "material": { "eq": "leather" } } }, { "image": { "exists": true } } ] }, "rules": [ { "effect": { "mode": "hard", "respect_user_filters": false, "type": "pin" }, "record_match": { "$and": [ { "brand": { "in": [ "nike", "adidas" ] } }, { "lbx:price": { "gte": 50, "lte": 200 } }, { "$or": [ { "condition": { "eq": "new" } }, { "warranty_months": { "gte": 12 } } ] }, { "$not": { "material": { "eq": "leather" } } }, { "image": { "exists": true } } ] } } ], "status": "draft", "timezone": "UTC"}Missing or invalid credentials
Canonical error body — every non-2xx response uses this shape.
object
Machine-readable error context; empty object when there is nothing to add.
object
Stable machine code naming why a well-formed request was refused: snake_case, prefixed by its domain — e.g. filter_unknown_field or cursor_mismatch. Safe to branch on; reason is not. Absent when the status code says all there is to say.
Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value.
One field-level reason a request was rejected.
object
Path to the offending value from the request root, e.g. ["body", "filters", 0, "operator"].
What is wrong with the value at loc.
Stable machine code for the problem, e.g. missing or string_too_short.
Human-readable, actionable error message.
Example generated
{ "exception_details": { "error_code": "example", "validation_errors": [ { "loc": [ "example" ], "msg": "example", "type": "example" } ] }, "reason": "example", "request_id": "example"}Authenticated but not permitted
Canonical error body — every non-2xx response uses this shape.
object
Machine-readable error context; empty object when there is nothing to add.
object
Stable machine code naming why a well-formed request was refused: snake_case, prefixed by its domain — e.g. filter_unknown_field or cursor_mismatch. Safe to branch on; reason is not. Absent when the status code says all there is to say.
Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value.
One field-level reason a request was rejected.
object
Path to the offending value from the request root, e.g. ["body", "filters", 0, "operator"].
What is wrong with the value at loc.
Stable machine code for the problem, e.g. missing or string_too_short.
Human-readable, actionable error message.
Example generated
{ "exception_details": { "error_code": "example", "validation_errors": [ { "loc": [ "example" ], "msg": "example", "type": "example" } ] }, "reason": "example", "request_id": "example"}Resource not found
Canonical error body — every non-2xx response uses this shape.
object
Machine-readable error context; empty object when there is nothing to add.
object
Stable machine code naming why a well-formed request was refused: snake_case, prefixed by its domain — e.g. filter_unknown_field or cursor_mismatch. Safe to branch on; reason is not. Absent when the status code says all there is to say.
Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value.
One field-level reason a request was rejected.
object
Path to the offending value from the request root, e.g. ["body", "filters", 0, "operator"].
What is wrong with the value at loc.
Stable machine code for the problem, e.g. missing or string_too_short.
Human-readable, actionable error message.
Example generated
{ "exception_details": { "error_code": "example", "validation_errors": [ { "loc": [ "example" ], "msg": "example", "type": "example" } ] }, "reason": "example", "request_id": "example"}State conflict, named by exception_details.error_code: campaign_archived — the campaign is archived (terminal — every update is rejected, including a status change); campaign_name_taken — another live campaign in the organization uses the name.
The canonical error body of a refused campaign write, with error_code typed.
object
The exception_details of a refused campaign write, naming why it was refused.
object
Why the write was refused.
Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value.
One field-level reason a request was rejected.
object
Path to the offending value from the request root, e.g. ["body", "filters", 0, "operator"].
What is wrong with the value at loc.
Stable machine code for the problem, e.g. missing or string_too_short.
Human-readable, actionable error message.
Example
{ "exception_details": { "error_code": "campaign_name_taken" }}Request validation failed. A field rejection lists each problem in exception_details.validation_errors, under a typed code; a targeting rejection lists every problem at once in exception_details.targeting_problems; a filter rejection lists its invalid conditions in exception_details.filter_problems, each naming the tree, rule and condition index it came from — only the trees past a cap when any is, since those are checked first.
The canonical error body of a rejected targeting set, with problems typed.
reason and request_id are the canonical fields; exception_details carries
the typed problems list.
object
The exception_details of a rejected targeting set: every problem found at once.
object
Every targeting violation found in one pass; never truncated. Named for what it carries, so it sits beside filter_problems on the same 422 without a client having to work out which of the two it was given. A 422 carries one list or the other, never both: the first check to refuse ends the request.
One targeting violation: a stable machine code plus the offending values.
object
Stable machine code of the violated rule.
The targeting axis the violation is about.
Human-readable explanation of the violation.
The offending values on that axis.
Human-readable, actionable error message.
The canonical error body of a rejected campaign filter, with filter_problems typed.
Inherits reason / request_id and only narrows exception_details, so where each
rejected condition sits is part of the published contract instead of prose in a message.
object
The exception_details of a rejected campaign filter: every bad condition at once.
object
Every invalid condition found in one pass, one entry per condition and reason — a condition refused the same way by several catalogs is reported once, listing them. Once the request has passed its schema checks, the depth and condition caps are checked first: when a tree is past one, only the trees past one are listed, each at the condition that put it over. Bounded by the request’s own condition caps, and never truncated.
One rejected condition: where it sits, what it names, and why it was refused.
object
The targeted catalogs whose inferred types refused the condition, sorted. Empty when the refusal is structural and therefore holds in every catalog.
Stable machine code for the kind of refusal — the same vocabulary a discovery request returns when it refuses a filter. Clients switch on this; message is for humans and may be reworded. filter_too_complex is the tree’s own refusal — past a depth or condition cap.
Zero-based index of the condition among that tree’s leaf conditions, in document order — counting the tree as you sent it, so the index points into the payload you are holding. For a stored rule a scope change re-checked, it counts the tree as GET returns it.
The field the condition references, exactly as it was sent. On a filter_too_complex refusal the condition is not itself wrong: it is where the tree went over its cap, and so where it has to be cut.
Human-readable explanation of why the condition is invalid. For a cap, it names the limit and, when pairing negations with exists changed the count, both counts.
Which condition tree the rejected condition sits in.
Human-readable, actionable error message.
The canonical error body of a campaign write that failed field validation, its codes typed.
object
The exception_details of a campaign write that failed field validation.
object
Stable machine code naming why a well-formed request was refused: snake_case, prefixed by its domain — e.g. filter_unknown_field or cursor_mismatch. Safe to branch on; reason is not. Absent when the status code says all there is to say.
Every field-level problem found, each naming where in the body it sits.
One field-level reason a campaign write was rejected, with its campaign codes published.
object
Path to the offending value from the request root, e.g. ["body", "filters", 0, "operator"].
What is wrong with the value at loc.
The stable machine codes a rejected schedule is reported under.
Carried on exception_details.validation_errors[].type. Clients switch on these; the
msg beside them is for humans and may be reworded.
The stable machine codes a rejected disclosure is reported under.
Human-readable, actionable error message.
Canonical error body — every non-2xx response uses this shape.
object
Machine-readable error context; empty object when there is nothing to add.
object
Stable machine code naming why a well-formed request was refused: snake_case, prefixed by its domain — e.g. filter_unknown_field or cursor_mismatch. Safe to branch on; reason is not. Absent when the status code says all there is to say.
Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value.
One field-level reason a request was rejected.
object
Path to the offending value from the request root, e.g. ["body", "filters", 0, "operator"].
What is wrong with the value at loc.
Stable machine code for the problem, e.g. missing or string_too_short.
Human-readable, actionable error message.
Example
{ "exception_details": { "targeting_problems": [ { "code": "catalog_scope_required", "dimension": "catalog" } ] }}Temporarily unable to serve the request; retry it unchanged after the Retry-After delay.
Canonical error body — every non-2xx response uses this shape.
object
Machine-readable error context; empty object when there is nothing to add.
object
Stable machine code naming why a well-formed request was refused: snake_case, prefixed by its domain — e.g. filter_unknown_field or cursor_mismatch. Safe to branch on; reason is not. Absent when the status code says all there is to say.
Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value.
One field-level reason a request was rejected.
object
Path to the offending value from the request root, e.g. ["body", "filters", 0, "operator"].
What is wrong with the value at loc.
Stable machine code for the problem, e.g. missing or string_too_short.
Human-readable, actionable error message.
Example generated
{ "exception_details": { "error_code": "example", "validation_errors": [ { "loc": [ "example" ], "msg": "example", "type": "example" } ] }, "reason": "example", "request_id": "example"}Was this page helpful?
Thanks.