--- title: Sponsored products description: Connect a retail-media provider account and place its sponsored results into specific channels and surfaces. slug: merchandising/sponsored-products docKind: guide hub: luigisbox-ai --- Sponsored products connects your retail-media platform to Luigi's Box AI and applies its placement decisions inside ranking. Two resources describe the setup: | Resource | Answers | |---|---| | **Provider** | Which retail-media account, and how to reach it. Organization-scoped. | | **Placement** | Where in this channel do its results appear, and how many? | One provider can be placed in many channels. One channel can hold placements from several providers. Both live on the platform API, and need a token for the `https://api..luigisbox.ai/platform` audience. ## Supported platforms | Platform | `config.platform` | Configuration | |---|---|---| | [Cruxo](https://cruxo.io/) | `cruxo` | [Cruxo](/merchandising/sponsored-products/providers/cruxo/) | Each platform has its own `config` shape, and `platform` selects which one the rest of `config` is read against. Contact Luigi's Box about a platform that is not on the list. ## Registering a provider A provider carries the connection definition for one retail-media account. The `config` in this example is Cruxo's shape: ```bash curl -X POST 'https://api.eu1.luigisbox.ai/platform/v1/sponsored-providers' \ -H 'Authorization: Bearer ' \ -H 'Content-Type: application/json' \ -d '{ "organization_id": "lbo_r2vn8c", "name": "Retail media — example.com", "status": "active", "config": { "platform": "cruxo", "base_url": "https://ads.example.com", "service_path": "adserve", "domain": "example.com", "area": "search", "size": "product", "product_id_path": "ad||productId", "position_path": "ad||position", "aliases": { "site": "outpost", "cdomain": "cdom", "size": "fmt" } } }' ``` | Field | Notes | |---|---| | `organization_id` | Immutable. A different organization is a different provider. | | `name` | Yours, for finding it later | | `status` | `active` or `disabled`. Defaults to `active`. | | `credentials` | Optional map, write-only. Accepted, never echoed back. | | `config` | The platform's contract for this account — see below | `credentials` exists for platforms that authenticate their callers, and is omitted for those that do not. When you do send credentials, the response reports `credentials_set: true` rather than the values. To replace them, `PATCH` a new `credentials` map; `{}` clears them. `config` and `credentials` each replace as a whole on a `PATCH`, rather than merging field by field, and each is validated as one unit. `config` must always restate `platform`, which cannot change — a different platform is a different account. An unrecognised key in `config` is rejected with `422` rather than stored and ignored. :::note[One variant per provider] Everything in `config` describes the platform's contract for that account and none of it varies by your channel or surface. An account that needs two different variants — say a search response and a product-page response — is two provider records. ::: ### Platform `config` The rest of `config` is the platform's contract for the account, and each platform defines its own fields: - [Cruxo](/merchandising/sponsored-products/providers/cruxo/) Some platform fields change what a placement can do: Cruxo's `position_path` decides whether fixed-position pinning happens at all. ## Placing it in a channel A placement binds one provider to one channel: ```bash curl -X POST 'https://api.eu1.luigisbox.ai/platform/v1/channels/lbn_4hj9tv/sponsored-placements' \ -H 'Authorization: Bearer ' \ -H 'Content-Type: application/json' \ -d '{ "sponsored_provider_id": "lbad_9v3npc", "status": "active", "surface_kinds": ["search"], "config": { "max_placements_pin": 2, "max_placements_promote": 3 } }' ``` The channel and the provider together are the placement's identity, so neither can be changed afterwards — to move a placement, delete it and create the new one. ### Narrowing where it applies Two optional axes, both defaulting to empty, which means the whole channel: | Field | Effect | |---|---| | `surface_kinds` | Only surfaces with these intents — `search`, `recommender`, `collection` | | `surface_ids` | Only these specific surfaces | They are mutually exclusive: a request carrying both is rejected with `422`. `surface_kinds` keeps applying as surfaces are added; `surface_ids` is fixed to the surfaces it names. ### Capping how much is sponsored `config` caps how much of a page sponsored content may take: | Field | Default | Range | Meaning | |---|---|---|---| | `max_placements_pin` | 20 | 0–100 | Most sponsored results placed at fixed positions | | `max_placements_promote` | 3 | 0–100 | Most sponsored results promoted within ranking | These are ceilings, not quotas: fewer are used when fewer are sold. Setting a cap to `0` turns off that kind of placement while leaving the rest of the setup in place. Sponsored results are placed by bid rather than by relevance; the caps bound how much of a results page they take. ## Turning it off `status: "disabled"` on a provider or a placement takes it out of serving while leaving it editable. Deleting a provider takes down every placement of it. Before you delete one, see where it is used: ```bash curl -G 'https://api.eu1.luigisbox.ai/platform/v1/sponsored-providers/lbad_9v3npc/sponsored-placements' \ --data-urlencode 'status=active' \ -H 'Authorization: Bearer ' ``` The result is every placement that deleting the provider would remove. ## Sponsored results and your own campaigns Sponsored placements and [campaigns](/merchandising/business-rules/overview/) both shape the same slate, and they are resolved by the same conflict rules — with one addition: at full parity, external decisions win. Full parity is narrow. Specificity and effect type are resolved first, so: - Your identity-level `ban` still removes a product a sponsored placement pinned. - Your `bury` still beats a sponsored `boost` at the same specificity, because effect type outranks the external tiebreak. - Where a sponsored decision and one of your rules are genuinely equivalent, the sponsored one is applied. See [Resolving conflicts](/merchandising/business-rules/conflicts/). ## Finding what is configured ```bash # Every provider for an organization curl -G 'https://api.eu1.luigisbox.ai/platform/v1/sponsored-providers' \ --data-urlencode 'organization_id=lbo_r2vn8c' \ --data-urlencode 'status=active' \ -H 'Authorization: Bearer ' # Every placement in a channel curl -G 'https://api.eu1.luigisbox.ai/platform/v1/channels/lbn_4hj9tv/sponsored-placements' \ -H 'Authorization: Bearer ' ``` Providers can also be filtered by `platform`. Both listings are [paginated](/api-basics/requests-and-responses/#pagination). ## See also - [Business rules](/merchandising/business-rules/overview/) — your own merchandising, and the conflict order - [Account structure](/platform/account-structure/) — channels and surfaces - [Analytics overview](/analytics/overview/) — measuring the effect on the page