Skip to main content

One endpoint, every table

Everything the Bilanc dashboard shows is served by a single endpoint. Each metric is an aggregation over one of Bilanc’s modelled tables (pull requests, reviews, issues, CI runs, AI copilot usage, posthook sessions, surveys, and so on). You pick the metric, and optionally the columns to group by, the date column to window on, and the time granularity. Endpoint: POST https://api.bilanc.co/metrics/{metric_type} Authentication: API key passed directly in the Authorization header (no Bearer prefix). Generate one from the Bilanc dashboard under Settings → API Keys.
The API key inherits the role and data visibility of the user who created it. See Permissions and data scoping.
Because any column of the underlying table can be used in group_by, the same endpoint also serves as a row-level export: group a count metric by the table’s primary key and you get one row per record, with whatever columns you ask for. That is how the dashboard renders its own tables and drill-downs. See Exporting Row-Level Data for the pattern, and Posthook Metrics for pulling AI agent sessions, prompts, files and commits.

Request body

Parameters

object
required
start_date is required for every metric except users-count and salary. end_date defaults to today. Dates are ISO 8601 (YYYY-MM-DD) and are compared against the column named in date_field.People and org filters apply to every table. Table-specific filters are ignored by tables that don’t have the column.
string[]
Columns to group by. Default [] (one aggregate row per date bucket).Valid values are any column of the metric’s source table (see the table reference) plus these derived fields, which work for every table:team_id, team_name, department, squad_id, squad_name, squad_level, descendant_squad_id, descendant_squad_name, manager_id, manager_name, manager_email, role, team_names, level, location, pr_author_team_id, pr_author_team_name, issue_author_team_id, issue_author_team_nameAn unknown field returns 400 with the list of valid fields for that metric, so the error message doubles as a column lookup.
team_id, team_name and department fan out one row per team or department the person belongs to. A user in two teams contributes to both rows.
string
Required for every metric except users-count and salary. Must be a date or timestamp column of the metric’s source table. It drives both the start_date/end_date window and the date_level bucketing. The valid date columns for each table are listed in the table reference. An invalid value returns 400 listing the valid date fields.
string
day, week, month, quarter, year, or hour. Omit to get a single aggregate row per group. When set, the response includes a {date_level}_date column (e.g. week_date) and every bucket in the window is returned, including empty ones. hour returns an hour_of_day column (0–23) and is only supported on single-metric requests.
string
SUM, AVG, MIN or MAX (case-insensitive). Required for value metrics (sizes, durations, tokens, costs, story points, lines). Count and rate metrics ignore it. Metrics that need it are marked in the metric list.
number
Drop rows where the metric value is below this threshold. Default 0 (no filtering). Useful with row-level exports, e.g. 1 to keep only sessions that produced AI code.
boolean
When true, every metric column is accompanied by a previous_ twin holding the value for the immediately preceding window of the same length. Default false.
string
Column to sort by. Any valid group_by field. Defaults to the date bucket.
string
ASC or DESC. Default ASC.
integer
Maximum rows to return, clamped to 1–200. Only applies to single-metric requests. get-multiple-metrics has no row cap.
boolean
Ignored on the API-key endpoint. Responses are always flat rows.

Response format

The response is a JSON array of rows. Each row has:
  1. A date column. {date_level}_date (e.g. day_date, month_date) when date_level is set, hour_of_day for hour, or date_level_not_set: true when it isn’t.
  2. One column per group_by field, named as requested.
  3. One or more metric columns. The column name depends on the metric (see All metrics). Value metrics prefix the aggregation in lowercase, e.g. sum_total_tokens, avg_cycle_time.
  4. With include_previous_period, a previous_ copy of each metric column.
Durations (cycle-time, review-time, posthook-active-time, etc.) are returned in seconds. Rates and ratios are 0–1 fractions, not percentages.

Permissions and data scoping

The API key acts as the user who created it. Row-level security is applied server-side on every query, exactly as in the dashboard: Additional rules:
  • salary, pull-requests-cost and productivity-cost return 403 unless the org has salary visibility on and the key owner has the can-view-salaries permission. The salary and pr_cost columns are silently removed from group_by otherwise.
  • Survey metrics (survey-*) return 403 for keys owned by anyone other than an Owner or Manager.
  • manager_id, manager_name and manager_email are silently removed from group_by for non-Owner keys.
  • Posthook install keys (the org-scoped keys used by the posthook CLI) are write-only and are rejected by this endpoint with 403.
Results are cached for five minutes per unique query. Underlying data refreshes hourly.

Tables and their columns

Each metric reads from exactly one table. Any column below is valid in group_by and order_by for the metrics of that table; columns marked with a date type are valid in date_field. Array and JSON columns (team_ids, squad_details, team_manager_details, pr_ai_summary, …) are technically groupable but rarely useful; use the derived join fields instead.
Default date field: pr_merged_at Date columns: pr_created_at, pr_merged_at, pr_closed_at, first_commit_at, last_commit_at, first_review_at, first_comment_at, first_activity, user_created_datepr_id, pr_number, pr_title, pr_body, pr_url, pr_state, pr_category, pr_ai_summary, repository, repository_url, source, branch_name, destination_branch, head_sha, additions, deletions, changed_files, total_changed_lines, total_reworked_lines, rework_rate, output_estimate, review_rounds_bucket, requested_reviewers_enriched, requested_teams_enriched, coding_time, pickup_time, review_time, total_cycle_time, commit_to_open, open_to_review, review_to_merge, time_to_first_comment, rework, ai_generated_lines, ai_committed_lines, ai_pct_of_code, total_ai_tokens, ai_output_tokens, top_model, pr_cost, cost_per_productivity, salary, user_id, merged_user_id, propelauth_user_id, name, role, location, level, departments, team_names, team_ids
Default date field: reviewed_at Date columns: reviewed_at, latest_reviewed_at, pr_created_at, pr_merged_at, pr_closed_atpr_review_id, pr_id, pr_title, pr_state, pull_request_url, html_url, repository, source, state, latest_review_state, changes_requested_count, comments_count, was_approved_by_requested_reviewer, review_rounds_bucket, time_to_first_comment, commit_id, additions, deletions, is_bot, user_login, merged_user_id, propelauth_user_id, name, role, location, level, departments, team_names, team_ids, pr_author_user_id, pr_author_merged_user_id, pr_author_propelauth_user_id, pr_author_name, pr_author_team_names, pr_author_team_ids
Default date field: commented_at Date columns: commented_atcomment_id, body, commit_id, pull_request_url, html_url, pr_id, pr_title, repository, is_bot, user_login, user_id, merged_user_id, propelauth_user_id, name, location, level, departments, team_names, team_ids, pr_author_user_id, pr_author_merged_user_id, pr_author_propelauth_user_id, pr_author_name, pr_author_team_names, pr_author_team_ids
Default date field: committed_at Date columns: committed_atcommit_id, sha, commit_message, committed_at, additions, deletions, total_changes, html_url, repository, repository_url, pr_id, pr_number, pr_title, pr_url, pr_state, author_id, author_name, merged_user_id, propelauth_user_id, name, location, level, departments, team_names, team_ids, pr_author_user_id, pr_author_merged_user_id, pr_author_propelauth_user_id, pr_author_name, pr_author_team_names, pr_author_team_ids
Default date field: event_at Date columns: event_atpr_id, event_type, event_state, event_url, sha, commit_message, additions, deletions, comment_body, pr_url, pr_number, pr_title, pr_state, repository, actor_merged_user_id, actor_name, merged_user_id, propelauth_user_id, name, location, level, departments, team_names, team_ids, pr_author_merged_user_id, pr_author_propelauth_user_id, pr_author_name, pr_author_team_names, pr_author_team_ids
Default date field: completed_at Date columns: created_at, started_at, completed_at, canceled_atissue_id, issue_title, issue_description, issue_url, source, state_name, state_id, state_type, story_points, project_id, project_name, cycle_id, cycle_number, label_ids, label_name, custom_category, branch_name, pr_details, total_cycle_time, pickup_time, creation_to_completion_time, ticket_age, assignee_id, assignee_email, merged_user_id, propelauth_user_id, name, role, location, level, departments, team_names, team_ids, creator_id, creator_name, creator_merged_user_id, creator_propelauth_user_id, creator_team_names, creator_team_ids, creator_departments
Default date field: created_at Date columns: created_at, updated_atissue_comment_id, comment, url, issue_id, issue_title, source, display_name, user_id, user_url, merged_user_id, propelauth_user_id, name, team_names, team_ids, issue_author_merged_user_id, issue_author_propelauth_user_id, issue_author_name, issue_author_team_names, issue_author_team_ids
Default date field: release_date Date columns: release_daterelease_id, version, notes, repository, pull_requests, author_source_user_id, merged_user_id, propelauth_user_id, name, role, location, level, departments, team_names, team_ids
Default date field: date Date columns: datesource, user_id, user_email, is_active, client_version, accepted_lines_added, accepted_lines_deleted, suggested_lines_to_add, suggested_lines_to_delete, total_lines_added, total_lines_deleted, total_accepts, total_rejects, total_applies, total_tabs_accepted, total_tabs_shown, chat_requests, composer_requests, agent_requests, cmd_k_usages, api_key_requests, bug_bot_usages, subscription_included_requests, usage_based_requests, most_used_model, model_provider, apply_most_used_extension, tab_most_used_extension, total_token_usage, total_cost, total_ai_loc, total_lines_changed, pr_count, total_daily_output_estimate, merged_user_id, propelauth_user_id, name, role, location, level, departments, team_names, team_ids
Default date field: run_created_at Date columns: run_created_at, run_started_at, run_completed_atworkflow_run_id, workflow_id, workflow_name, workflow_state, workflow_path, run_title, run_number, run_attempt, run_status, run_conclusion, run_url, repository, head_branch, head_sha, source, run_duration_s, macos_run_duration_s, windows_run_duration_s, ubuntu_run_duration_s, total_jobs, successful_jobs, failed_jobs, avg_job_duration_ms, jobs_details, total_artifacts, total_artifact_size_bytes, artifacts_details, estimated_workflow_run_cost_usd, credits_used, associated_pull_request_ids, actor_login, actor_type, source_user_id, merged_user_id, propelauth_user_id, name, role, location, level, departments, team_names, team_ids
No date window (start_date and date_field are not used). Date columns: last_active_at, user_created_datemerged_user_id, propelauth_user_id, name, main_email, role, location, level, salary, sources, source_types, tenant_seats, number_of_seats_used, departments, team_names, team_ids
Default date field: date Date columns: date, started_at, ended_atsession_id, engineer_email, engineer_name, agent_slug, model_slug, model_provider, repo_id, repo_name, remote_url, branch, input_tokens, output_tokens, cache_read_tokens, cache_creation_tokens, total_tokens, active_minutes, generated_lines, files_edited, committed_lines, commits_contributed, user_id, merged_user_id, propelauth_user_id, name, role, location, level, departments, team_names, team_idsFull column descriptions on the Posthook Metrics page.
Default date field: date Date columns: date, message_tsmessage_id, session_id, message_seq, role, source, agent_slug, message_text, tool_calls, turn_minutes, engineer_email, merged_user_id, team_names, team_ids
Default date field: date Date columns: date, first_edit_ts, last_edit_tssession_id, file_path, edits, lines_generated, lines_committed, commits_touched, engineer_email, merged_user_id, team_names, team_ids
Default date field: date Date columns: date, committed_atsession_id, commit_id, sha, short_sha, branch, message, author_email, lines_added, lines_removed, files_changed, lines_attributed, attribution_source, confidence, files_touched, pr_id, pr_source, pr_title, pr_url, pr_state, engineer_email, merged_user_id, team_names, team_ids
Default date field: final_response_submitted_at Date columns: final_response_submitted_at, response_created_at, response_updated_at, recipient_final_response_submitted_at, sent_atsurvey_response_id, survey_id, survey_name, template_id, survey_status, survey_question_id, survey_template_question_id, section_id, section_title, section_order, question_order, question_text, response_type, answer, answer_value, answer_comment, answer_other_text, survey_recipient_id, recipient_type, recipient_email, respondent_propelauth_user_id, respondent_email, merged_user_id, propelauth_user_id, name, role, location, level, departments, team_names, team_ids
Default date field: created_at Date columns: created_at, sent_at, survey_email_sent_at, final_response_submitted_atsurvey_recipient_id, survey_id, survey_name, template_id, survey_status, recipient_type, recipient_email, merged_user_id, propelauth_user_id, name, role, location, level, departments, team_names, team_ids

All metrics

Agg marks metrics that require aggregation; the response column then starts with the lowercase aggregation (shown as {agg}). Multi only marks metrics that are accepted by get-multiple-metrics but not as a single metric_type path.

Pull requests (pull_requests)

Reviews, comments, commits, events

Issues

Releases and CI

AI copilots (ai_copilot)

Seat-level usage from Cursor, GitHub Copilot and similar connections.

Posthook (AI agent attribution)

Definitions and examples on the Posthook Metrics page.

People and surveys

Special metric types

These metric_type values are not table metrics: