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_fromRequired |
"YYYY-MM-DD" |
Start of the period, inclusive. |
date_toOptional |
"YYYY-MM-DD" |
End of the period, inclusive. Defaults to today. |
aggregateOptional |
"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_byOptional |
"user" |
Split each period into one row per user. Omit for one row per period. |
usersOptional |
list[string] | Restrict to these users. Omit for every user. See Get customers. |
filter_users_based_on_featuresOptional |
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_tagsOptional |
{tag_key: list[string] | string} |
Restrict to users carrying these tags (AND across tag_key, OR within a tag_key’s values). |
apply_creditsOptional |
boolean | Apply free AI credits discounts to cost. Defaults to false. |
limitOptional |
integer | Max number of rows to fetch. Defaults to 100, max 1000. |
cursorOptional |
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. |