Scheduling & A/B tests
Two adjacent surfaces that drive most growth integrations. Both work exclusively at the link level — there's no profile-wide schedule or test.
Schedule a link
scheduleLink accepts a ScheduleConfig with go-live and expire
timestamps. Either is optional, but you must supply at least one:
mutation Schedule($linkId: ID!, $config: ScheduleConfig!) {
scheduleLink(linkId: $linkId, config: $config) {
link { _id scheduleConfig { liveAt expiresAt timezone } }
}
}{
"linkId": "65f...",
"config": {
"liveAt": "2026-08-01T18:00:00.000Z",
"expiresAt": "2026-08-08T18:00:00.000Z",
"timezone": "Europe/London"
}
}scheduledLinks returns every link with an active or upcoming schedule
for the authenticated user — handy for "Coming up" admin views.
Timezones matter at the boundary
We store liveAt/expiresAt as UTC, but the editor records the
authoring timezone in timezone. If you change a user's timezone in
your app, refetch and re-render before letting them edit a schedule —
otherwise an 18:00 launch slips by an hour.
Create an A/B test
A/B tests on Linkstacked compare two link variants and route traffic 50/50 with deterministic, sticky bucketing per visitor.
mutation CreateABTest($input: CreateABTestInput!) {
createABTest(input: $input) {
test { _id status variants { label url ctr } }
}
}{
"input": {
"linkId": "65f...",
"variants": [
{ "label": "Variant A", "url": "https://...", "title": "Stream now" },
{ "label": "Variant B", "url": "https://...", "title": "Listen here" }
]
}
}The same surface exposes pauseABTest, resumeABTest, and
endABTestWithWinner(testId, winnerLabel) so an automated pipeline can
end a test as soon as significance is reached.
Read live test results
abTestReport(testId) returns variant-level click-through rates,
significance, and a flag for the leading variant. Poll it on whatever
cadence makes sense for your dashboard — the API caches per-second
aggregations server-side, so a 5–10s poll is friendly.