> ## Documentation Index
> Fetch the complete documentation index at: https://www.help.creatora.io/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> When building or modifying an integration with the Creatora API, start with https://www.help.creatora.io/en/api/build-with-ai.md. Retrieve the current GraphQL SDL from https://api.creatora.io/sdl before relying on API schema information.

# Get revenue by Course

> Allocate retained Order revenue to Courses using historical Offer prices.

Compare revenue retained from purchases completed in a period, allocated to each Course. The report includes successful, refunded and disputed Orders in their current state.

This example uses **September 1, 2026 at 00:00 UTC** (`1788220800000`) through **October 1, 2026 at 00:00 UTC**, exclusive (`1790812800000`). Replace both timestamps for your period and timezone. The request starts one millisecond earlier because the API date bounds are strict.

## Request

<RequestExample>
  ```graphql theme={null}
  {
    orders(status: { equals: [succeeded, refunded, disputed] }, closedOn: { range: [1788220799999, 1790812800000] }) {
      id closedOn amountNetRevenue
      offerSnapshot {
        price
        items {
          allocatedPrice
          itemData {
            __typename
            ... on OfferSnapshotItemCourseData { course { id name } }
          }
        }
      }
    }
  }
  ```
</RequestExample>

<ResponseExample>
  ```json Illustrative response theme={null}
  {
    "data": {
      "orders": [
        {
          "id": "55555555-5555-4555-8555-555555555555",
          "closedOn": 1788224400000,
          "amountNetRevenue": 80.0,
          "offerSnapshot": {
            "price": 100.0,
            "items": [
              {
                "allocatedPrice": 100.0,
                "itemData": {
                  "__typename": "OfferSnapshotItemCourseData",
                  "course": {
                    "id": "22222222-2222-4222-8222-222222222222",
                    "name": "Drawing Essentials"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
  ```
</ResponseExample>

## Use the result

For each historical Offer item, multiply the Order’s retained revenue by `allocatedPrice / offerSnapshot.price`. This follows Creatora’s Course allocation model.

```javascript theme={null}
const start = 1788220800000;
const end = 1790812800000;
const orders = response.data.orders.filter(order =>
  order.closedOn !== null && order.closedOn >= start && order.closedOn < end
);
const totals = new Map();
const needsReview = [];
for (const order of orders) {
  const snapshot = order.offerSnapshot;
  if (snapshot.price <= 0) {
    if (order.amountNetRevenue !== 0) needsReview.push(order.id);
    continue;
  }
  const courseIds = snapshot.items
    .filter(item => item.itemData?.__typename === "OfferSnapshotItemCourseData")
    .map(item => item.itemData.course.id);
  const allocatedTotal = snapshot.items.reduce((sum, item) => sum + item.allocatedPrice, 0);
  if (new Set(courseIds).size !== courseIds.length ||
      snapshot.items.some(item => item.allocatedPrice < 0) ||
      Math.abs(allocatedTotal - snapshot.price) > 0.01) {
    needsReview.push(order.id);
    continue;
  }
  for (const item of snapshot.items) {
    if (!item.itemData) { needsReview.push(order.id); continue; }
    if (item.itemData.__typename !== "OfferSnapshotItemCourseData") continue;
    const course = item.itemData.course;
    const row = totals.get(course.id) ?? { courseId: course.id, name: course.name, revenue: 0 };
    row.revenue += order.amountNetRevenue * item.allocatedPrice / snapshot.price;
    totals.set(course.id, row);
  }
}
const rows = [...totals.values()].map(row => ({
  ...row, revenue: Number(row.revenue.toFixed(2))
})).sort((a, b) => b.revenue - a.revenue);
```

The report measures current retained revenue for purchases completed in the selected period. Refunds are reflected in those purchases, rather than grouped by refund date. Profit after fees and the built-in lifetime Course total are separate measures.

Services and custom items keep their own allocation, so Course totals may be smaller than the Platform total. Review Orders marked `needsReview` before reporting a complete allocation. The flag identifies nonzero revenue with a zero-priced snapshot, invalid allocations, repeated Course items or historical items whose `itemData` is null.

The `closedOn` filter in the processing example selects completed purchases; the API date filter also returns Orders created in the period. The request has no list limit. For large reports, request shorter periods and deduplicate Orders by `id`. Amounts use the Platform currency. Manually registered Orders are included.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.