Account Metrics
Six totals for one account over a date range, counted the same way the account's own OnePath Dashboard counts them.
curl -H "Authorization: Bearer YOUR_KEY" \
"https://app.onepath.ai/api/reporting/v1/accounts/42/metrics?from=2026-08-01&to=2026-08-31"
{
"account": { "id": 42, "name": "Wahoo Plumbing", "time_zone": "America/Chicago" },
"period": { "from": "2026-08-01", "to": "2026-08-31" },
"metrics": {
"leads": 120,
"appointments": 48,
"booking_rate": 40.0,
"won_revenue": 96000.0,
"average_ticket": 2000.0,
"pipeline_revenue": 150000.0
},
"generated_at": "2026-09-03T10:00:00Z"
}
Take the id from /accounts. Numbers are numbers: rates are percentages as floats, money is US dollars as decimals. Nothing comes back as a formatted string.
Dates
from and to are both required, in YYYY-MM-DD, and inclusive. A range may cover at most 366 days. Anything else is a 422 invalid_date_range.
Days start and end in the account's own time zone (the time_zone in the response), not yours and not UTC. A booking at 23:30 local time on to is included; one at 00:30 the next local morning is not. For a monthly report, ask for the first to the last day of the month and you get exactly that month as the contractor experienced it.
What each number means
| Key | Counts | Notes |
|---|---|---|
| leads | conversations that became a qualified lead | a conversation is one visitor contact; qualified means OnePath judged it a real service request |
| appointments | conversations whose most recent opportunity was won | won means the job was booked |
| booking_rate | appointments ÷ leads × 100 | one decimal; 0.0 when there are no leads |
| won_revenue | the value of won opportunities | US dollars |
| average_ticket | won_revenue ÷ appointments | two decimals; 0.0 when there are no appointments |
| pipeline_revenue | the value of opportunities that are open, being followed up, handed to a person, or won | the same figure the Dashboard shows as estimated revenue |
Each of these matches what the account owner sees on their own Dashboard for the same period, so when you put a number in front of a client it agrees with theirs.
Reporting on several accounts
There is no rollup endpoint. Call /accounts once, then this endpoint once per account. Add the totals yourself, and recompute the two rates from your sums rather than averaging them:
const key = "YOUR_KEY";
const base = "https://app.onepath.ai/api/reporting/v1";
const range = "from=2026-08-01&to=2026-08-31";
const headers = { Authorization: `Bearer ${key}` };
const { accounts } = await fetch(`${base}/accounts`, { headers }).then((r) => r.json());
const rows = await Promise.all(
accounts.map((a) => fetch(`${base}/accounts/${a.id}/metrics?${range}`, { headers }).then((r) => r.json()))
);
const leads = rows.reduce((sum, r) => sum + r.metrics.leads, 0);
const appointments = rows.reduce((sum, r) => sum + r.metrics.appointments, 0);
const bookingRate = leads ? Math.round((appointments / leads) * 1000) / 10 : 0;
Results are cached for six hours per account and range, so a nightly job that walks every account is well within the rate limits.