Performance

Get cost, bucketed by period and optionally grouped by user, alongside each of the project’s key metrics’ value and cost-per-unit for the same period.

Performance is computed on internal projects. On a revenue-linked project (tracked by revenue, not key metrics), this route returns a 400: use Get margin instead.

import weflayr

client = weflayr.client(api_key="wf-...")
const weflayr = require('weflayr');

const client = weflayr.client({ apiKey: 'wf-...' });
# Passed as a Bearer token on every request
export WEFLAYR_API_KEY="wf-..."

Get performance

from weflayr.openapi.models import PerformanceInput

client.get_performance(body=PerformanceInput.from_dict({
    "date_from": "2026-06-01",
    "aggregate": "week",
    "group_by": "user",
    "user_tags": {"region": ["EU", "NA"], "plan": "premium"},
}))
await weflayr.api.getPerformance({
  client,
  throwOnError: true,
  body: {
    dateFrom: '2026-06-01',
    aggregate: 'week',
    groupBy: 'user',
    userTags: { region: ['EU', 'NA'], plan: 'premium' },
  },
});
curl -X POST https://app.weflayr.com/api/performance/ \
  -H "Authorization: Bearer $WEFLAYR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "date_from": "2026-06-01",
    "aggregate": "week",
    "group_by": "user",
    "user_tags": {"region": ["EU", "NA"], "plan": "premium"}
  }'

Output:

{
  "rows": [
    {
      "date_from": "2026-06-01", "date_to": "2026-06-07", "user": "u_123", "cost": 342.87,
      "key_metrics": {
        "Meetings booked": {"value": 134.0, "total_cost": 342.87, "cost_per_unit": 2.56},
        "Tickets resolved": {"value": 556.0, "total_cost": 342.87, "cost_per_unit": 0.62}
      }
    },
    {
      "date_from": "2026-06-01", "date_to": "2026-06-07", "user": "u_456", "cost": 128.05,
      "key_metrics": {
        "Meetings booked": {"value": 40.0, "total_cost": 128.05, "cost_per_unit": 3.20}
      }
    }
  ],
  "next_cursor": null,
  "has_more": false
}

user is omitted when group_by isn’t set.

Input params: passed in the request body.

Field Accepts Behaviour
date_from
Required
"YYYY-MM-DD" Start of the period, inclusive.
date_to
Optional
"YYYY-MM-DD" End of the period, inclusive. Defaults to today.
aggregate
Optional
"day" | "week" | "month" | "quarter" | "year" | "all" One row per period; "all" collapses the whole date range into a single row (per group_by, if set). Defaults to "day".
group_by
Optional
"user" Split each period into one row per user. Omit for one row per period.
users
Optional
list[string] Restrict to these users. Omit for every user. See Get customers.
filter_users_based_on_features
Optional
list[string] Restrict to users who used any of these feature tags in the period (i.e. if a user did not use the feature, all its rows are removed)
user_tags
Optional
{tag_key: list[string] | string} Restrict to users carrying these tags (AND across tag_key, OR within a tag_key’s values).
apply_credits
Optional
boolean Apply free AI credits discounts to cost. Defaults to false.
limit
Optional
integer Max number of rows to fetch. Defaults to 100, max 1000.
cursor
Optional
string The route is paginated: pass the previous page’s next_cursor to fetch the next page. PS: has_more from the output says whether another page exists.