Dashboard KPIs API Reference

Pull the same KPI bar shown on your Hermon dashboard for any date range.

Overview: This endpoint returns the exact metrics your Hermon dashboard shows — new leads, booked calls, close rates, cash collected, and more — for a date range you choose, alongside the same figures for the preceding period so you can track change over time. Values are computed by Hermon the same way the dashboard computes them, so numbers always line up with what you see in the app.

Get KPI Bar

Returns the KPI metrics for the requested period plus the comparison period. Provide a start and end date; both are calendar dates in your organization's timezone.

GET/api/external/dashboard/kpis

Query Parameters

ParameterTypeRequiredDescription
fromstring (YYYY-MM-DD)requiredStart of the reporting period (inclusive). A calendar date interpreted in your organization’s timezone.
tostring (YYYY-MM-DD)requiredEnd of the reporting period (inclusive). A calendar date interpreted in your organization’s timezone.
user_scopestring (comma-separated user IDs)optionalRestrict the metrics to specific team members. Each id is matched on the role that member holds (setter, closer, or triager). Omit to include the whole team. Use the Team Members endpoint to resolve ids.
call_categorystring (enum)optionalLimit the metrics to a single call category: SALES_CALL, COACHING_CALL, or TRIAGE_CALL. Omit to include all categories.
Dates & the comparison period: from and toare whole calendar days in your organization's timezone — the range always covers the full to day. The comparison period (previous_value on each metric) is the equal-length range immediately before your selected period, chosen automatically.

Code Examples

curl -X GET "https://api.hermon.io/api/external/dashboard/kpis?from=2026-09-01&to=2026-09-30" \
  -H "x-api-key: sk_live_your_key_here"

Response Fields

FieldTypeDescription
metricsarrayThe KPI values for the requested period. Each entry carries value, previous_value, and growth_percent (see Metric Object below).
available_metricsarrayCatalogue of every metric that can appear, with its key, label, description, type, and group ("kpi", "finance", or "meta").
currencystring | nullISO currency code for all monetary metrics (your organization’s currency).
current_periodobjectThe resolved { start_date, end_date } for the requested range.
previous_periodobjectThe { start_date, end_date } of the comparison period (the equal-length range immediately before current_period).
avg_growth_percentnumberAverage growth across the returned metrics.
meta_setup_statusstringWhether Meta Ads is connected for the organization ("ok", "not_connected", or "no_selection"). Meta metrics are zero when not connected.
meta_setup_messagestring | nullHuman-readable note about the Meta Ads setup status, when relevant.

Metric Object

Each entry in metrics (and the catalogue in available_metrics) has the following shape.

FieldTypeDescription
keystringStable identifier for the metric (e.g. "closing_rate_booked_percent", "cash_collected").
labelstringHuman-readable name as shown on the dashboard.
descriptionstringPlain-English definition of exactly how the metric is calculated.
valuenumber | nullThe metric value for the selected period. null when it is not applicable (e.g. a rate with no denominator).
previous_valuenumber | nullThe same metric for the immediately preceding period of equal length, for comparison.
growth_percentnumber | nullPercentage change from previous_value to value.

Response Example

Trimmed to a representative subset — the live response returns the full metric set.

json
{
  "status": "success",
  "message": "KPI bar fetched successfully",
  "data": {
    "available_metrics": [
      {
        "key": "calls_booked",
        "label": "Booked Calls",
        "description": "Unique leads with at least one appointment (any outcome) in the period, using their latest appointment.",
        "type": "number",
        "group": "kpi"
      },
      {
        "key": "cash_collected",
        "label": "Cash Collected",
        "description": "Sum of PAID payments in the period minus any associated succeeded refunds.",
        "type": "currency",
        "group": "kpi"
      }
    ],
    "metrics": [
      {
        "key": "new_leads",
        "label": "New Leads",
        "description": "Total number of new leads created within the period, based on lead creation date.",
        "value": 42,
        "previous_value": 37,
        "growth_percent": 13.51
      },
      {
        "key": "calls_booked",
        "label": "Booked Calls",
        "description": "Unique leads with at least one appointment (any outcome) in the period, using their latest appointment.",
        "value": 18,
        "previous_value": 21,
        "growth_percent": -14.29
      },
      {
        "key": "contract_signed",
        "label": "Contracts Signed",
        "description": "Number of contracts with status SIGNED and signed_at within the period.",
        "value": 6,
        "previous_value": 4,
        "growth_percent": 50
      },
      {
        "key": "closing_rate_booked_percent",
        "label": "Close Rate (Booked)",
        "description": "Booked calls in the period that produced a signed contract ÷ booked calls in the period × 100.",
        "value": 33.33,
        "previous_value": 19.05,
        "growth_percent": 74.96
      },
      {
        "key": "cash_collected",
        "label": "Cash Collected",
        "description": "Sum of PAID payments in the period minus any associated succeeded refunds.",
        "value": 12500,
        "previous_value": 9800,
        "growth_percent": 27.55
      }
    ],
    "avg_growth_percent": 30.25,
    "currency": "usd",
    "current_period": {
      "start_date": "2026-09-01",
      "end_date": "2026-09-30"
    },
    "previous_period": {
      "start_date": "2026-08-01",
      "end_date": "2026-08-31"
    },
    "meta_setup_status": "ok",
    "meta_setup_message": null
  }
}

Scoping to Specific Team Members

Per-rep numbers: pass user_scopewith one or more team-member ids (comma-separated) to see the KPIs for just those people — for example a single closer's close rate and cash collected. Each id is matched on the role that member holds. Resolve ids with the GET /api/external/team-members endpoint. Omit user_scope for whole-team totals.

Error Responses

400Missing or invalid date parameters
json
{
  "status": "error",
  "message": "from must be a date in YYYY-MM-DD format"
}
401Missing or invalid API key
json
{
  "status": "error",
  "message": "Invalid or revoked API key"
}
429Rate limit exceeded
json
{
  "status": "error",
  "message": "Rate limit exceeded for this organization. Retry after the number of seconds in the Retry-After header."
}