Scheduled Distributions

Every AI Pricing Model is already running a traffic distribution. A Scheduled Distribution is a second distribution with a start and an end: while its window is open it takes over the model's traffic completely, and when the window closes the model returns to its always-on split on its own.

Reach for one when a creative needs the traffic for a fixed period and then needs to get out of the way. A holiday offer that runs from December 20 to December 27, a launch-week price, a Black Friday paywall, a regional sale. You set the window once, and there is nothing to switch back afterwards.

A scheduled window is built from placements that are running live A/B tests, which makes the window measurable by design: the seasonal creative goes in front of users, and the test running behind that placement tells you whether it beat its control. Inside the window each user is assigned to one placement and stays there, so a window is a real user-level read and not a per-request coin flip.

Schedules live on the model's Traffic Control tab. Click AI Pricing Models in the left sidebar, open the model, select the Traffic Control tab, and scroll to Scheduled Distributions. For how the always-on distribution works, see Traffic Control.

Before you start: a schedule targets placements, never paywall IDs, and every placement a schedule points at has to be eligible as a traffic target. Eligible means the placement has exactly one audience, that audience is the all-users audience rather than a segment, and that audience is running a live A/B test. So the setup is: build the seasonal creative, put it behind a placement of its own, launch an A/B test on that placement's all-users audience, then schedule the placement. See Create Placements and A/B Tests Overview.

Create a scheduled distribution

  1. Open the model's Traffic Control tab, scroll to Scheduled Distributions, and click Add Schedule.

  2. In step 1 of the Add Scheduled Distribution dialog, search for the placement that hosts the seasonal test and select it. Each placement in the list carries a chip for every routing its audiences use, AI Model, A/B Test or Paywall. Pick one whose chip reads A/B Test. The list is not filtered to eligible placements and the chip does not say whether the test is live, so confirm the test is running before you pick it. Click Continue to Traffic Allocation.

    Screenshot of step 1 of the Add Scheduled Distribution dialog, showing a searchable list of placements where each row carries chips for the routing its audiences use: AI Model, A/B Test, or Paywall.
  3. In step 2, Traffic Allocation, set the placement to 100 with the slider or the number field. The status bar reads Total must equal 100% until the weights add up, then switches to Ready to schedule. Click Continue to Schedule.

    Screenshot of step 2 of the Add Scheduled Distribution dialog, titled Traffic Allocation, showing a slider paired with a number input for the selected placement and a status bar reading Total must equal 100%.
  4. In step 3, Schedule Activation, set the Start Date & Time, tick Set end date, then set the End Date & Time. Days already covered by another schedule are greyed out in the calendar. Click Confirm Schedule.

    Screenshot of step 3 of the Add Scheduled Distribution dialog, titled Schedule Activation, with Start Date and Time filled in, the Set end date checkbox ticked, and End Date and Time filled in.
  5. The schedule appears in the Scheduled Distributions list with its window, a Scheduled badge, and its own Total: 100%. Confirming saves it, so there is no separate Save Changes step.

    Screenshot of the Scheduled Distributions list showing one saved schedule row that reads 12/20/2026 at 9:00 AM with Ends: 12/27/2026 at 11:59 PM, next to a Scheduled badge and a Total: 100% readout.

The saved schedule above runs from 12/20/2026 at 9:00 AM to 12/27/2026 at 11:59 PM. Until 9:00 AM on December 20 the model keeps serving its always-on split, and from that moment until the end of the window every request goes to the placement behind the seasonal creative.

Confirm Schedule is where eligibility is checked. If a placement you picked is not a valid target, the save is rejected and the reason appears on screen. The three you can hit are Placement "..." cannot be a traffic redirect target: it must have exactly one audience (found N)., Placement "..." cannot be a traffic redirect target: its audience must be the all-users audience, not a segment. and Placement "..." cannot be a traffic redirect target: its audience must be running a live A/B test. Nothing is saved when this happens, so fix the placement or pick a different one and run the dialog again.

A window does not have to be a full takeover. Select more than one placement in step 1 and give each its own weight in step 2, so a window can run 70% on the sale creative and 30% somewhere else. Every placement in the window has to be eligible on its own, and the weights have to total exactly 100.

What happens when the window opens and closes

  • The start time is inclusive, the end time is exclusive. The schedule is serving from the start instant, and the instant the end time arrives it is not.

  • A running schedule fully replaces the always-on distribution. Nothing is blended and the always-on weights are ignored for the duration. On screen, the always-on section is retitled Default Distribution and marked Paused, and the running schedule becomes the Current Distribution. Paused there only means a schedule is currently overriding it.

  • Reversion is automatic. At the end time, traffic returns to the always-on distribution on the very next request. Nothing needs to be clicked, and the schedule row then reads Completed. A completed schedule stays in the list until you delete it.

  • No background job runs. The active window is worked out per request against the server clock, so a window that has just opened or just closed takes effect immediately. The earliest day the date picker will accept is today, so the way to start a schedule right now is to pick today with a time that has already passed. It starts serving on the next request.

Who sees what during the window

While a window is open and the paywall request carries a profile ID, the split is resolved per user rather than per request. Each profile is hashed into one of the window's placements and stays on it for the whole window, so a user who opens the paywall twice sees the same placement both times.

  • Opening a window draws membership fresh. The hash is seeded on the schedule itself, and each schedule is a distinct distribution with its own identity, separate from the always-on one. So who lands on which placement inside the window has no relation to who was in which slice under the always-on split. When the window closes, the always-on assignment resumes exactly as it was, untouched.

  • This only matters for split windows. A window that gives one placement 100% sends every user to that placement, so there is nothing to reshuffle. Plan around this only when a window splits traffic across two or more placements.

  • Editing a schedule keeps its users, deleting and re-adding does not. Changing a saved schedule's dates or weights in place keeps the same schedule, so membership carries through the edit. Deleting a schedule and adding it again creates a new one, and its users are drawn fresh.

  • Changing a weight moves the boundary, not the hash. Widen a placement's share inside a window and the users already on it stay on it while more are added from the rest, so nobody is moved off. Narrow it and the users nearest the boundary move off. With several placements in one window the shares are laid out in the order you added them, so changing an earlier one also shifts where the later ones start and stop.

  • The variant a user sees inside the test does not move. Variant assignment is bucketed on the A/B test's own salt together with the same profile ID, independently of Traffic Control, so opening or closing a window does not change which variant a user gets. Relaunching the test is what reshuffles variants.

  • Requests with no profile ID are drawn per request. With no user to hash, the window's split falls back to a weighted random draw on every request, and the A/B test behind the placement draws randomly too. Send the profile ID if you want the window to read as a user-level test.

Plan the window around these

  • Set an end date for a fixed window. Set end date is what makes the window close on its own. Left unticked, the schedule is open-ended, and because an open-ended window covers all time after its start, the calendar then caps every other schedule at the day before it starts. For a seasonal takeover, always tick it.

  • Windows may not overlap. Only one scheduled window may cover any given moment, and a save that would create an overlap is rejected with Scheduled groups must not overlap. Please ensure each scheduled group has a distinct time range. The calendar disables every day another schedule touches, including its final day, so the earliest a next window can start is the day after the previous window's end date. Ending windows at the end of a day keeps that gap down to a minute.

  • Dates and times are the browser's local timezone. They are entered and displayed in whatever timezone your browser is in, with no timezone label on screen, and they are stored and compared in UTC. A teammate in another timezone will read the same schedule as a different clock time, so agree on whose clock the window is set to.

  • To end a window early, delete the schedule. There is no pause. Deletion takes effect immediately, with no confirmation prompt, and traffic returns to the always-on distribution on the next request.

  • The window covers this model's traffic. A takeover reaches the users who hit this model's placement and match its audience, not everyone using your app.

Good to know

A window's traffic is attributed to the A/B test it lands in, not to the model. A paywall served through a scheduled placement comes back carrying abTestId, and on the Web API also abTestName, while the model's aiPricingModelId is left off that response. The SDK endpoint carries abTestId but not abTestName. The answer is byte for byte what a placement running that test directly would return, so anything keyed on the response treats the two the same. The way to read how a window performed is to read the A/B test that ran in it over the window's dates. The full attribution matrix is on A/B Tests in Traffic Control.

Deleting a placement removes any allocation pointing at it, including allocations inside a saved schedule, with no warning. That leaves the schedule totalling less than 100, and the rows that remain are renormalised at serve time, so both the effective split and each user's slice boundary shift away from the numbers on screen. If you clean up placements, reopen Traffic Control afterwards and check that each schedule still totals 100.

Saving a schedule does not touch the model's own paywalls or its weight. That write-back happens only when you save the always-on distribution, see Good to know on the Traffic Control overview.

See also