Working with Optimize
The Optimize API lets you read the optimizations running on your site and how they are performing. Use it to build reporting dashboards, sync results into other tools, or check which variation is winning.
Every endpoint is a read-only GET request.
sites:read scope and a Webflow site with the Optimize add-on.optimize-site instead of webflow-site.Choose an endpoint
Start with List Optimize IDs and List optimizations. They return the IDs that every other endpoint needs.
Core concepts
Optimize IDs
Optimize identifies your data with an optimizeId instead of a site ID. Every other endpoint takes an optimizeId in its path.
Call List Optimize IDs to see which optimizeId belongs to which site. Each entry includes a resource with the site’s siteId and displayName.
If an optimizeId matches more than one resource your token can access, other endpoints return 409 Conflict.
Optimizations
An optimization has one of three types:
test: A traditional A/B test. It shows different versions of your content to a share of your traffic and declares a winner once the result reaches statistical significance.personalize: A manual personalization. It shows a variation to visitors who match rules you define, and it runs until you stop it. It has no winner.aiOptimize: An AI-optimized test. It uses AI to deliver the best-performing variation to each visitor.
Each optimization has one or more variations. Reports for tests and AI-optimized optimizations compare each variation against the base variation.
List optimizations returns live and draft optimizations by default. Pass status to include ready, archived, or off optimizations.
The optimization type changes what each result includes:
Intervals
An interval is a snapshot of an optimization’s configuration, such as which variations are live and which goal is the target goal. When you change the configuration in a way that affects results, the current interval ends and a new one starts.
Each report covers one date range inside one interval. A range that crosses from one interval into the next is rejected. To choose a range, take the start and end of an interval from List optimizations. An interval with no end is still running.
Goals
A goal defines the action that counts as a conversion. Each interval has its own goals, and exactly one is the target goal, marked isPrimary: true. The target goal is the one Optimize uses to measure success. For AI-optimized optimizations, it’s also what the AI optimizes for. Other goals are used only for reporting.
Reports measure one goal at a time. Pass goalId to choose it. If you omit goalId, the report uses the interval’s target goal. Get valid IDs from List optimization goals.
A goal’s metricType changes the response:
conversion: Results show conversions and conversion rate.value: Results also include the totalvalueand the averagevaluePerConversion.
A goal’s scope is the unit it counts conversions in: session, user, or pageview.
Reading results
Each variation in a report includes the following core metrics:
sessions: A period of continuous activity by a visitor. A session ends after 30 minutes of inactivity.users: The number of unique visitors who saw the variation. A visitor who returns counts as one user.conversions: How many times visitors took the action the goal tracks.conversionRate: Conversions divided by sessions, returned as a fraction. For example,0.1193means 11.93%.
lift is also a fraction. A lift of 0.19 means the variation converts 19% better than the base variation.
To learn what each metric means, see Review your optimization results.
Date ranges
Pass intervalStart and intervalEnd as UTC timestamps ending in Z, for example 2026-09-01T00:00:00Z. Offsets and date-only values aren’t accepted.
Two rules apply to every report:
intervalEndmust be later thanintervalStart.intervalStartcan’t be earlier than 18 months ago.
Dimensions and filters
A dimension is an attribute of a visitor, such as country, device, or traffic source. Use dimensions to split results with groupBy on Get audience insights, or to narrow any report with filter.
Call List dimensions for the dimensions available in your date range. groupBy accepts any dimension except urlParameter.
filter uses bracket notation with in to include values or nin to exclude them. Use indexed brackets for multiple values:
Separate dimensions combine with AND. Values within one dimension combine with OR. A filter can name at most 20 dimensions, with at most 50 values per operator and 500 values in total.
id. Use each row’s value in your filter, not its label. For example, the country dimension returns GB as the value and United Kingdom as the label.Pagination
List optimizations and List dimension values return results in pages. Use pageSize to set the page size (default 100, maximum 200). When a response includes nextCursor, pass it as cursor to get the next page. A response without nextCursor is the last page.
A cursor stays tied to the request that created it. For List optimizations, repeat the same status. For List dimension values, repeat the same dimension, date range, and filter. You can change pageSize between pages.
Rate and concurrency limits
Optimize applies two limits in addition to standard authentication:
- Rate limit: The standard per-minute Data API rate limit, based on the site plan.
- Concurrency limit: Each access token can have one Optimize request in flight at a time, across all Optimize endpoints.
If either limit is exceeded, the request fails with 429 Too Many Requests and a Retry-After header. Send Optimize calls one at a time, and retry after the Retry-After interval.
Errors
Optimize validates each request and returns 400 Bad Request with a code that identifies the rule that failed:
Other requests can fail with these errors:
Walkthrough: check which variation is winning
Imagine you’re reporting to a client on a hero headline A/B test. They want to know which variation is winning, and whether the result holds for visitors in the United Kingdom. This walkthrough finds the test, reads its results, and then splits them by country.
Find the Optimize ID
List the Optimize IDs your token can access, then find the entry whose resource.siteId matches your site.
The response lists each optimizeId with the site it belongs to:
Find the optimization and its interval
List the live optimizations for that optimizeId.
Find the test you want and note its optimizationId. Then choose an interval. Here, “Don’t Panic hero headline” has two intervals, and the example shows the second. It started on 2026-08-15T17:30:00.000Z and has no end, so it’s still running. Its target goal is “Towel purchase”.
Get the results
Request the results for a date range inside that interval. Because you omit goalId, the report measures the target goal.
Each entry in variations is one variation. The comparison object shows how it compares with the base variation. Here, the second variation has a conversion rate of 11.9% against the base variation’s 10%, which is a lift of about 19%. It’s marked as the winner with a statistical significance of 0.97.
Split the results by country
Call Get audience insights with groupBy=country to see whether the result holds across regions. The request takes the same date range and goalId options as the results endpoint.
Each variation now includes one entry per country in segments. For the non-base variation, trendDirection shows how it compares with the base variation in that segment. confidence shows how much to trust that reading.
This example shows the United Kingdom segment for the non-base variation. It’s trending up with a confidence of 0.93.
From here, try another endpoint to answer a different question:
- Get performance over time: whether the lift is steady or fades
- List optimization goals: other goals to measure, using
goalId - List dimension values: values to use in a
filterfor one audience
To browse every endpoint, see Choose an endpoint.