---
title: "Yielded sales report"
method: GET
path: "/shop/reports/yielded-sales"
tags: ["Reports"]
---

# Yielded sales report

`GET /shop/reports/yielded-sales`

Paginated list of every sale where a yield rule moved the price — up at
peak, or down to fill quiet spells. Sales made when no rule applied
(the implicit standard tier) are not included.

Each row is a snapshot taken at the time of sale: the rule, tier, fill
rate, and baseline price are read from provenance stored when the price
was resolved, never recomputed from the current rule or price
configuration. Editing, renaming, or deleting a rule after a sale does
not change how that sale reports.

Money fields are integers in the minor units of each row's `currency`.
Totals are grouped per currency and are never summed across currencies.
Rows whose `status` is `refunded` or `cancelled` stay in the list,
flagged, but are excluded from the revenue and net-uplift totals so the
numbers reconcile with other sales reports.

Results default to most recent sale first, tiebroken on `id` so
ordering is stable when sales share a timestamp. The response also
includes a CSV variant when requesting with `Accept: text/csv`; for
large date ranges or background delivery use
[`/shop/reports/yielded-sales/queue`](/endpoints/Reports#queueYieldedSalesExport).

Requires the `reports.view` permission (`reports.download` for the CSV
variant). Sites without the `advanced_yield_management` feature
respond `404`.

## Query parameters

- `site_id` string, uuid, required
- `page` integer
- `per_page` integer
- `date_from` string, date
- `date_to` string, date
- `search` string
- `offering_ids` string[]
- `offering_types` string[]
- `yield_rule_ids` string[]
- `tiers` string[]

## Response `200`

The report was successfully generated.

- YieldedSalesReportResponse
  - `data` YieldedSale[], required
    - `id` string, object-id, required — The ID of the basket item the yielded price was sold on.
    - `basket_id` string, object-id, required
    - `order_ref` string, required
    - `sold_at` string, date-time, required — When the order was submitted, expressed in the site's local timezone.
    - `status` 'completed' | 'refunded' | 'cancelled', required — `completed` sales count towards the report totals. `refunded` and `cancelled` sales stay listed for reconciliation but are excluded from the revenue and net-uplift totals.
    - `offering_id` string, required — The offering the sale was for.
    - `offering_type` 'appointment' | 'area_booking' | 'session' | 'package', required — The kind of offering a rule applies to. Limited to offerings booked against a service date, which is what demand is measured over.
    - `offering_name` string, required — The offering's name at the time of sale. Kept even when the offering has since been renamed or deleted — check `offering_exists` before treating it as current.
    - `offering_exists` boolean, required — Whether the offering still exists (and is not deleted).
    - `yield_rule_id` string, uuid, required — The yield rule that moved the price, as recorded at the time of sale. The rule may have been edited or deleted since — check `yield_rule_exists` before linking to it.
    - `yield_rule_exists` boolean, required — Whether the yield rule still exists (and is not deleted).
    - `adjustment` YieldRuleAdjustment, required — The change a rule makes to the price it applies to. Signed, so a rule can discount to shift demand as well as add a premium at peak.
      - `type` 'amount' | 'percentage', required — Whether the adjustment is a fixed amount in minor units, or a percentage of the price it applies to.
      - `value` integer, required — Integer minor units when `type` is `amount`, matching `standard_price`; whole percent when `type` is `percentage`.
    - `tier` 'low' | 'high' | 'peak', required — Groups yielded sales in reporting. Descriptive only — it never affects the adjustment a rule makes. Sales made when no rule applied report as an implicit standard tier, which is why it is absent here. The [yielded sales report](/endpoints/Reports#listYieldedSales) lists and totals sales by this tier.
    - `fill_rate_percent` integer, nullable, required — The demand measurement (practitioner utilisation or room occupancy, whichever satisfied the rule's trigger) at the time of sale, as a whole-number percentage. `null` when no measurement was recorded.
    - `currency` string, required — The ISO-4217 currency code the row's monetary amounts are denominated in, in integer minor units.
    - `baseline_price` integer, nullable, required — What the item would have cost without the yield adjustment, in integer minor units. `null` when the offering had no standard price at the time of sale, in which case the row is excluded from the net-uplift totals.
    - `price_paid` integer, required — What the item actually sold for, in integer minor units.
    - `delta_amount` integer, nullable, required — `price_paid` minus `baseline_price`, in integer minor units. Negative when a low-tier rule discounted the price. `null` when `baseline_price` is `null`.
    - `delta_percent` integer, nullable, required — The delta as a whole-number percentage of `baseline_price`. Negative when a low-tier rule discounted the price. `null` when `baseline_price` is `null`.
  - `meta` PaginationMeta, required — Counts and positional information for the current page of a list response. Use `current_page` and `last_page` to drive pagination UI, `total` for result counts, and `per_page` to confirm the page size the server actually applied (which may differ from the requested value when capped).
    - `from` integer, required — The item number from which this results set starts from
    - `to` integer, required — The item number from which this results set ends at
    - `total` integer, required — The total number of results
    - `current_page` integer, required — The current page number
    - `last_page` integer, required — The page number of the last result set
    - `per_page` integer, required — The number of results per page
    - `path` string, required — The path of this api request
  - `links` PaginationLinks, required — Hypermedia navigation links for paging through a list response. Each property is a fully-qualified URL that preserves the original query string (filters, sort, page size) and only swaps the `page` parameter. `next` and `prev` are `null` at the ends of the result set; `first` and `last` are always present.
    - `first` string, required — The url of the first page for the paginated results set
    - `next` string, nullable, required — The url of the next page for the paginated results set
    - `prev` string, nullable, required — The url of the previous page for the paginated results set
    - `last` string, required — The url of the last page for the paginated results set
  - `totals` YieldedSalesTotals, required — Aggregates over every row matching the active filters, not just the current page. Monetary totals are grouped per currency and never summed across currencies; `refunded` and `cancelled` sales and rows with no `baseline_price` are excluded as described on each field.
    - `count` integer, required — The number of yielded sales matching the active filters, including refunded and cancelled sales.
    - `currencies` YieldedSalesCurrencyTotals[], required — One entry per currency appearing in the filtered results. A single site reports in one currency, so this usually has one entry; historical currency changes produce one entry per currency rather than a sum across them.
      - `currency` string, required — The ISO-4217 currency code the totals in this entry are denominated in, in integer minor units.
      - `revenue` integer, required — Total `price_paid` across completed yielded sales in this currency. Refunded and cancelled sales are excluded.
      - `net_uplift` integer, required — Total `delta_amount` across completed yielded sales in this currency — what yielding earned versus the baseline prices. Low-tier discounts net against high- and peak-tier increases, so this can be negative. Rows with no `baseline_price` are excluded.
      - `tiers` YieldedSalesTierTotals[], required — The same totals broken down by reporting tier.
        - `tier` 'low' | 'high' | 'peak', required — Groups yielded sales in reporting. Descriptive only — it never affects the adjustment a rule makes. Sales made when no rule applied report as an implicit standard tier, which is why it is absent here. The [yielded sales report](/endpoints/Reports#listYieldedSales) lists and totals sales by this tier.
        - `count` integer, required — The number of yielded sales in this tier, including refunded and cancelled sales.
        - `revenue` integer, required — Total `price_paid` across completed sales in this tier, in integer minor units. Refunded and cancelled sales are excluded.
        - `net_uplift` integer, required — Total `delta_amount` across completed sales in this tier, in integer minor units. Typically negative for the `low` tier, since its rules discount the price. Rows with no `baseline_price` are excluded.

## Other responses

- `400` — The request failed.
- `401` — The user is unauthenticated
- `403` — The authenticated user does not have permission.
- `422` — The request didn't pass validation

---

[API](https://skmtc.dev/try/apis/trybe-api.md) · [All operations](https://skmtc.dev/try/apis/trybe-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/try/trybe-api/revisions/f37f92702da5/schema)
