> ## Documentation Index
> Fetch the complete documentation index at: https://bilanc.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# People & Survey Metrics

> Headcount, roster exports, salary, and developer-experience survey results

## People metrics (`user_metrics`)

One row per person Bilanc knows about, merged across every connected source. These two metrics are the only ones that take **no date window**: `start_date` and `date_field` are not required and are ignored.

<ParamField path="users-count" type="count">
  Distinct people. Response column `number_of_users`. The dashboard uses this with `group_by` to build the roster that other metrics are merged onto, so teams with no activity still appear.
</ParamField>

<ParamField path="salary" type="aggregation required">
  Salary aggregate. Response column `{agg}_salary`. Returns `403` unless the org has salary visibility enabled and the key owner has the `can-view-salaries` permission.
</ParamField>

### Example: export the roster

```bash theme={null}
curl -X POST 'https://api.bilanc.co/metrics/users-count' \
  -H 'Authorization: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "filters": {},
    "group_by": ["merged_user_id", "name", "main_email", "role", "level", "location", "team_names", "departments", "sources", "last_active_at", "user_created_date"]
  }'
```

```json theme={null}
[
  {
    "date_level_not_set": true,
    "merged_user_id": "b3f1…",
    "name": "Jordan Lee",
    "main_email": "jordan@example.com",
    "role": "member",
    "level": "Senior",
    "location": "London",
    "team_names": ["Platform"],
    "departments": ["Engineering"],
    "sources": ["github", "jira", "posthook"],
    "last_active_at": "2026-09-09T17:20:11+00:00",
    "user_created_date": "2024-03-11",
    "number_of_users": 1
  }
]
```

### Example: headcount by team

```bash theme={null}
curl -X POST 'https://api.bilanc.co/metrics/users-count' \
  -H 'Authorization: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "filters": {},
    "group_by": ["team_name"]
  }'
```

<ResponseField name="filters" type="object">
  `member`, `team`, `departments`, `locations`, `levels`, `squad_ids`, `squad_levels`, `manager_ids`, and `source_types` (the integration types the person was merged from, e.g. `github`, `jira`).
</ResponseField>

## Survey metrics

Bilanc developer-experience surveys are modelled as two tables: `survey_recipients` (who each survey was sent to) and `survey_responses` (one row per answered question).

<Warning>
  Survey metrics return `403` unless the API key was created by an **Owner or Manager**.
</Warning>

<ParamField path="survey-recipients-count" type="count">
  Distinct recipients. Table `survey_recipients`, response column `survey_recipients_count`.
</ParamField>

<ParamField path="survey-completed-recipients-count" type="count">
  Recipients who submitted a final response. Table `survey_recipients`, response column `survey_completed_recipients_count`.
</ParamField>

<ParamField path="survey-responses-count" type="count">
  Distinct answered questions. Table `survey_responses`, response column `survey_responses_count`.
</ParamField>

<ParamField path="survey-respondents-count" type="count">
  Distinct people who answered, counting both Bilanc users and external invitees. Table `survey_responses`, response column `survey_respondents_count`.
</ParamField>

### Example: completion rate per survey

```bash theme={null}
curl -X POST 'https://api.bilanc.co/metrics/get-multiple-metrics' \
  -H 'Authorization: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "filters": {"start_date": "2026-01-01", "end_date": "2026-09-30"},
    "group_by": ["survey_id", "survey_name", "survey_status"],
    "metrics": ["survey-recipients-count", "survey-completed-recipients-count"],
    "date_fields": {
      "survey-recipients-count": "created_at",
      "survey-completed-recipients-count": "created_at"
    }
  }'
```

### Example: every answer to one survey

```bash theme={null}
curl -X POST 'https://api.bilanc.co/metrics/survey-responses-count' \
  -H 'Authorization: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "filters": {
      "start_date": "2026-01-01",
      "survey_ids": ["4c1e…"]
    },
    "group_by": ["survey_response_id", "section_title", "question_order", "question_text", "response_type", "answer_value", "answer_comment", "answer_other_text", "team_names", "final_response_submitted_at"],
    "date_field": "final_response_submitted_at",
    "order_by": "question_order",
    "order_direction": "ASC",
    "limit": 200
  }'
```

Responses are anonymous at the question level in the dashboard; the API applies the same role gating rather than hiding columns, so treat exports accordingly.

### Parameter notes

<ResponseField name="date_field" type="string">
  `survey_responses`: `final_response_submitted_at` (default), `response_created_at`, `response_updated_at`, `sent_at`.
  `survey_recipients`: `created_at` (default), `sent_at`, `survey_email_sent_at`, `final_response_submitted_at`.
</ResponseField>

<ResponseField name="filters" type="object">
  Both tables: `survey_ids` plus the standard people filters. `survey_responses` also accepts `survey_template_question_ids` and `survey_response_types`.
</ResponseField>

<ResponseField name="group_by" type="string[]">
  Useful survey columns: `survey_id`, `survey_name`, `survey_status`, `section_id`, `section_title`, `survey_template_question_id`, `question_text`, `response_type`, `answer_value`, `answer_comment`, `answer_other_text`, `recipient_type`.
</ResponseField>
