Revenue
Manage revenue programmatically instead of uploading CSVs. On an internal project, go to Manage Key metrics 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-..."
Set revenue
A customer can have several lines in the same month (in case of multiple billings):
from weflayr.openapi.models import SetRevenueInput
client.set_revenue(body=SetRevenueInput.from_dict({
"rows": [
{"customer_name": "c_123", "amount": 1200.50, "month": "2026-06"},
{"customer_name": "c_456", "amount": 800, "month": "2026-06"},
]
}))
await weflayr.api.setRevenue({
client,
throwOnError: true,
body: {
rows: [
{ customerName: 'c_123', amount: 1200.50, month: '2026-06' },
{ customerName: 'c_456', amount: 800, month: '2026-06' },
],
},
});
curl -X POST https://app.weflayr.com/api/revenue/ \
-H "Authorization: Bearer $WEFLAYR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"rows": [
{"customer_name": "c_123", "amount": 1200.50, "month": "2026-06"},
{"customer_name": "c_456", "amount": 800, "month": "2026-06"}
]
}'
Output:
{"ok": true, "rows_inserted": 2}
Input params:
| Field | Accepts | Behaviour |
|---|---|---|
rowsRequired |
array of row objects | The revenue lines to book, described in the table below. Up to 1,000 per call. |
upsertOptional |
boolean (default false) |
If a row’s revenue_id already exists (c.f. rows parameters below), overwrite it instead of throwing an error. |
Each object inside rows accepts:
| Row field | Accepts | Behaviour |
|---|---|---|
customer_nameRequired |
string | The same customer_name you stamp on your LLM calls when propagating metadata, so revenue and AI cost land on the same customer. |
amountRequired |
number | The value to book. |
monthRequired* |
"YYYY-MM" |
The calendar month the value belongs to. |
month_start, month_endRequired* |
"YYYY-MM" |
Bill over a multi-month period (e.g. quarterly) instead of a single month. amount is split evenly over the period. |
revenue_idOptional |
String | An id for the revenue row over which uniqueness is checked, typically from a billing management system. |
* Set either month, or both month_start and month_end, never both forms on the same row.
API values are their own revenue source, alongside Stripe and CSV. Sources add up: if you post revenue for a customer-month that also has a CSV upload or a Stripe sync, Weflayr assumes it is the sum. We recommend using one source only to avoid double counting.
Get revenue
client.get_revenue(customer_names=["c_123", "c_456"])
await weflayr.api.getRevenue({
client,
throwOnError: true,
query: { customerNames: ['c_123', 'c_456'] },
});
curl "https://app.weflayr.com/api/revenue/?customer_names=c_123&customer_names=c_456" \
-H "Authorization: Bearer $WEFLAYR_API_KEY"
Output:
{
"rows": [
{"revenue_id": "b3f2b160-6e12-4f1a-9c3d-0a2e7c9b5d41", "customer_name": "c_123", "metric_name": "revenue", "month": "2026-06", "amount": 1200.5, "source": "api"},
{"revenue_id": "f7a1d8e0-9b3c-4a2f-8e6d-1c4b7a9f2e05", "customer_name": "c_123", "metric_name": "revenue", "month": "2026-06", "amount": 300.0, "source": "stripe"},
{"revenue_id": "a1c9e4d2-7b60-4f8a-9e2d-3c4b7a9f1e08", "customer_name": "c_456", "metric_name": "revenue", "month": "2026-06", "amount": 800.0, "source": "api"}
],
"next_cursor": null,
"has_more": false
}
Input params: passed in the query string.
| Field | Accepts | Behaviour |
|---|---|---|
customer_namesOptional |
list[string] | Specify the names of the customers from which revenue should be fetched. Not setting it means “all customers”. |
limitOptional |
integer (default 100, max 1000) |
Numbers of rows to fetch. |
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. |
Delete revenue
client.delete_revenue(customer_names=["c_123", "c_456"])
await weflayr.api.deleteRevenue({
client,
throwOnError: true,
query: { customerNames: ['c_123', 'c_456'] },
});
curl -X DELETE "https://app.weflayr.com/api/revenue/?customer_names=c_123&customer_names=c_456" \
-H "Authorization: Bearer $WEFLAYR_API_KEY"
Output:
{"ok": true, "rows_deleted": 3}
Input params: passed in the query string.
| Field | Accepts | Behaviour |
|---|---|---|
customer_namesRequired |
list[string] | Delete all these customers’ API-booked revenue. |
month_start, month_endOptional |
"YYYY-MM" |
Narrow the delete to this inclusive month range. Omit both to delete every API-booked value of the named customers. |
PS: CSV uploads and Stripe syncs are managed by their own source and cannot be deleted via this route