Get ad performance
well_get_ad_performanceGet what the ads cost and what they really brought in over a window of days: ad spend, the conversions and the sales value each ad platform claims, the real sales, and the ratios Well computes from them. Use it for ROAS, cost per order, revenue per visit, conversion rate, or spend against sales; use well_list_daily_metrics for raw daily rows.
window names the days: dates, yesterday, last_days (ending yesterday) or an event (black_friday: Friday through Cyber Monday, year_offset -1 for last year's). The result's window gives the resolved from_date and to_date, the workspace timezone they were resolved in, and the event with its year. window.calendars says which day each side counts: ad and visits figures follow each ad account's or analytics property's own reporting day (source_account_day), and sales follow the UTC day of their issue time (utc_day), so the sides can differ by a few hours at each end of the window. window.has_data false means no source holds a row in those days at the level read, no ad source holds spend at another level, and no readable sale was recorded, for example an event still to come: say so, unless missing names unreadable_sales_rows, which says sales rows exist that Well cannot read, and never move to another window or another year yourself. Repeating the read at a level that other_levels_with_spend names keeps the same window, so do that when it names one.
totals holds the window. real_sales is what the store and the invoices really sold, net of tax, each sale counted once (A paid sales order counts, its unpaid rest is owed.); paid_orders counts those sales: each paid store order, and each issued invoice whether or not it is paid. claimed_conversions and claimed_sales_value are what the platforms claim: never revenue, and they can count one sale twice across platforms. ratios are computed, never stored: blended_roas = real sales / spend, claimed_roas = claimed sales value / spend, cost_per_paid_order = spend / paid orders. State a figure as the tool returns it; never recompute or add it.
visits_by_source lists each analytics source's visits on its own, never added together, each with revenue_per_visit = real sales / that source's visits and conversion_rate = paid orders / that source's visits (a fraction, 0.0159 is 1.59 %). Each carries its definition (what it counts), or unknown: then never guess what the source counts from its name. visits_comparable is true only when two or more sources state the same definition; otherwise their definitions differ or are unknown, so state each source's visits as its own figure and never add them.
Money is per currency and never converted. A null figure or ratio was not measured: it is never zero. missing says why: no_source_rows (no connected source reported it), no_sales_source (no store or invoicing tool connected), not_attributable (orders and visits name no campaign, ad account or channel, so those groups carry spend and claims only), sales_read_truncated, several_currencies (no ratio across currencies), source_stale (a source feeding the figure last synced before the window closed (a window that includes today closes at the start of today for this check), so the ratios built on it are null: never read its figure as complete), unreadable_sales_rows (some sales rows have no net amount or no currency, so real sales leave them out), unreadable_sales_check_failed (that check could not run, so say real sales may leave some rows out), day_in_progress (the window includes today: quote the totals as recorded so far, and state no ROAS, cost per order, revenue per visit, conversion rate or spend share for the totals or today until the day closes; the groups of earlier days in a split by day keep their ratios, and the planned spend is null), window_not_started (the window starts after today: its days have not happened, so never state 0 sales, 0 orders or 0 spend for them). When ad_spend is null and other_levels_with_spend names a level, call again with that level.
Each connected source in ad_sources, sales_sources and visits_sources gives synced_at, fresh_enough and window_rows (none when it wrote nothing for the window, for example a source that stopped syncing): when a source is not fresh enough, or a figure is source_stale, say its figures may be old, and offer well_request_sync with its id. A sync cannot clear day_in_progress or window_not_started, so never offer one for those. window.partial_day true means the window includes today: its totals are what is recorded so far, and the ratios of the totals and of today are null with day_in_progress. The latest days may still change even when the window ended: platforms restate recent days, and a platform's day can follow another timezone than the workspace's. sales_side_unknown true means the workspace's own company is unknown and real sales may include purchases. With group_by, each group carries spend_share: its spend over the window's total spend, per currency (a fraction). With target_orders, plan.planned_spend = the window's spend × target orders / its paid orders, in ratios.currency; null when the window has no cost per paid order. groups_truncated true means more than 200 groups: narrow the range before you rank them.
When the token authorizes one workspace, call this directly — no workspace call is needed first. When it authorizes several, this read will not guess which one you mean: pass workspace_id on the call.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| level | No | The level the ad figures are read at: campaign (default), ad_set or ad. One level per call. | |
| window | Yes | The days to read. dates: from_date to to_date. yesterday: the day before today. last_days: the days that end yesterday. event: black_friday, Friday through Cyber Monday. yesterday, last_days and event read the workspace's calendar. | |
| group_by | No | Split the window: source (each ad account), project (each campaign, ad set or ad of the level), traffic_channel, or day (at most 31 days). The totals only when absent. | |
| workspace_id | No | Target workspace. Omit when the token authorizes one workspace. Required when it authorizes several: this read reports one workspace's own figures and will not choose which. | |
| target_orders | No | A number of paid orders to plan for: the read returns the spend it takes at the window's cost per paid order. | |
| conversation_id | No | The conversation id returned by the previous Well result, in its meta under well/conversation_id, in its structuredContent, or in its JSON text block. Pass it back on every call in the same conversation, including a call a card makes, so the chosen workspace and the earlier answers still apply. It decides the conversation on its own: nothing the host states about the session replaces it. Omit it only on the first call of a conversation. | |
| workspace_scope | No | Restrict this call to the family: the token's primary workspace plus the company workspaces under it that you are a member of. Unrelated authorized workspaces drop out of the read; row reads merge across the family, while a per-workspace figure still reports exactly one workspace. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| plan | No | ||
| error | No | ||
| level | No | ||
| groups | No | ||
| totals | No | ||
| window | No | ||
| missing | No | ||
| success | Yes | ||
| ad_sources | No | ||
| sales_sources | No | ||
| visits_sources | No | ||
| conversation_id | No | The conversation this result belongs to. Pass it back as the conversation_id argument on every later Well call in the same conversation. | |
| newly_connected | No | Tools that connected to this workspace since the last result and that no session was told about yet, oldest first. Present only when at least one tool is new. The connected-line rule says when to tell an entry; when it does, one line per entry, in the person's language: "<name> is connected.". Never fold several entries into one sentence. Each entry comes back once, on one result only: never repeat its line later. | |
| groups_truncated | No | ||
| visits_comparable | No | ||
| resolved_workspace | No | The workspace that answered, when the caller named none and the token authorizes several. | |
| sales_side_unknown | No | ||
| conversation_id_note | No | Present only when the server opened a fresh lane, stating that no choice recorded earlier was read. | |
| conversation_id_source | No | Where the conversation id came from: the host's own request meta, the caller's argument, or a fresh lane the server opened. | |
| other_levels_with_spend | No |