Skip to main content

Export Efficiency and Productivity Metrics Using the Harness SEI API

Last updated on

SEI 2.0 provides APIs to export Productivity and Efficiency metrics in CSV format for team, developer, and organization-level reporting. There are two available APIs:

  • V2 Export API (recommended): Asynchronous, scalable, and designed for large datasets and org-wide exports.
  • Legacy Reports API: Synchronous export API for team and contributor reporting use cases.

Both APIs return CSV output but differ in execution model and request structure.

FeatureV2 Export APILegacy Reports API
Execution modelAsynchronousSynchronous
ScaleSupports org-level exportsBest for team-level exports
WorkflowJob-based export lifecycleSingle request/response

Harness recommends the following best practices:

  • Prefer team-scoped exports over full organization exports when possible.
  • Use metricGroups instead of long lists of individual metrics.
  • Poll export status instead of repeatedly recreating export jobs.
  • Schedule exports during off-peak hours for large organizations.

Select an API

The V2 Export API provides asynchronous export of productivity metrics at the developer, team, or organization scope. The export workflow looks like:

This API is designed for large organization exports, automated reporting pipelines, scheduled data exports, historical analytics processing, and bulk developer or team reporting.

Authentication

All V2 export requests require authentication headers.

HeaderValue
authorizationApiKey <YOUR_SEI_API_KEY>
Content-Typeapplication/json

You must also include the following query parameters on all requests:

ParameterDescription
projectIdentifierHarness project identifier
orgIdentifierHarness organization identifier

Create Export Job

Create an asynchronous export job.

POST /v2/insights/productivity/exports

Request Body

{
"scope": {
"orgTreeName": "Engineering",
"teamId": "456"
},
"dateRange": {
"start": "2024-01-01",
"end": "2024-12-31"
},
"metricGroups": ["activity", "velocity", "volume", "quality", "collaboration"], // You can provide `metricGroups` only, `metrics` only, or both `metricGroups` and `metrics`; if both are provided, the API merges and deduplicates the metrics automatically.
"metrics": ["PR_Merged", "Work_Completed"],
"options": {
"aggregation": "mean",
"aggregationLevel": "developer",
"granularity": "monthly",
"format": "csv"
}
}

Configuration

FieldDescription
scopeDefines the export scope (organization or team)
dateRangeStart and end dates for the export period
metricGroupsGroups of metrics to export.
metricsIndividual metrics to export
aggregationAggregation method used for metric calculations
aggregationLevelExport data grouped by developer (each CSV row represents a developer and time period) or team (each CSV row represents a team and time period)
granularityReporting interval (weekly, monthly, quarterly)
formatExport format (csv)

To export an entire organization tree:

{
"scope": {
"orgTreeName": "Engineering" // This exports all teams and developers within the specified org tree.
}
}

To export a specific team:

{
"scope": {
"orgTreeName": "Engineering",
"teamId": "456" // This exports metrics only for the specified team.
}
}

Example Request

curl -X POST "${BASE_URL}/v2/insights/productivity/exports?projectIdentifier=${PROJECT_ID}&orgIdentifier=${ORG_ID}" \
-H "Content-Type: application/json" \
-H "authorization: ApiKey <YOUR_SEI_API_KEY>" \
-d '{
"scope": {
"orgTreeName": "Engineering",
"teamId": "456"
},
"dateRange": {
"start": "2024-01-01",
"end": "2024-12-31"
},
"metricGroups": ["activity", "velocity"],
"options": {
"aggregation": "mean",
"aggregationLevel": "developer",
"granularity": "monthly",
"format": "csv"
}
}'

Responses

202 Accepted

Returned when a new export job is successfully created.

{
"exportId": "exp_7a8b9c0d",
"createdAt": "2025-12-29T10:00:00Z",
"message": "Export created successfully"
}
200 OK (Existing Export Reused)

Returned when an identical export already exists.

{
"exportId": "exp_7a8b9c0d",
"createdAt": "2025-12-29T09:58:00Z",
"message": "Using existing export with identical parameters"
}

Check Export Status

Poll the export status endpoint until the export reaches the completed state.

GET /v2/insights/productivity/exports/{exportId}

Example Response

{
"exportId": "exp_7a8b9c0d",
"status": "completed",
"createdAt": "2025-12-29T10:00:00Z",
"completedAt": "2025-12-29T10:02:15Z",
"download": {
"url": "/v2/insights/productivity/exports/exp_7a8b9c0d/download",
"filename": "developer-insights-2024.csv",
"contentType": "text/csv"
}
}

The following export statuses are available:

StatusDescription
queuedExport is waiting to be processed
processingExport is currently being generated
completedExport is ready for download
failedExport failed due to an error
cancelledExport was cancelled by user

Download Export

Downloads the generated CSV file.

GET /v2/insights/productivity/exports/{exportId}/download

Large exports may be automatically compressed as .gz files.

Example Request

curl -X GET "<BASE_URL>/v2/insights/productivity/exports/<EXPORT_ID>/download?projectIdentifier=<HARNESS_PROJECT_ID>&orgIdentifier=<HARNESS_ORG_ID>" \
--header 'authorization: Apikey <SEI_API_KEY>' > ~/<PATH>/<FILE_NAME>.csv.gz

List Exports

Retrieve historical export jobs.

GET /v2/insights/productivity/exports

The following query parameters are available:

ParameterDescription
statusFilter by export status
scopeall (default) or mine
teamIdFilter by team ID
createdByFilter by user ID
dateFromFilter exports created after a date
dateToFilter exports created before a date
limitMaximum results returned (default 50, max 100)
pagePage number (0-based)
sortBycreatedAt, completedAt, status
sortOrderasc or desc

The following example demonstrates how to create an export job, poll for export completion, and download the generated CSV file.

import time
import requests

BASE_URL = "<HARNESS_BASE_URL>"
API_KEY = "YOUR_SEI_API_KEY"

HEADERS = {
"SEI_API_KEY": API_KEY,
"Content-Type": "application/json"
}

PROJECT = "<HARNESS_PROJECT_ID>"
ORG = "<HARNESS_ORG_NAME>"

payload = {
"scope": {"orgTreeName": "<ORG_TREE_NAME>"},
"dateRange": {"start": "2024-01-01", "end": "2024-12-31"},
"metricGroups": ["activity", "velocity"],
"options": {
"aggregation": "mean",
"aggregationLevel": "developer",
"granularity": "monthly",
"format": "csv"
}
}

create_url = f"{BASE_URL}/v2/insights/productivity/exports?projectIdentifier={PROJECT}&orgIdentifier={ORG}"
resp = requests.post(create_url, headers=HEADERS, json=payload)
export_id = resp.json()["exportId"]

status_url = f"{BASE_URL}/v2/insights/productivity/exports/{export_id}?projectIdentifier={PROJECT}&orgIdentifier={ORG}"

while True:
status = requests.get(status_url, headers=HEADERS).json()["status"]
if status == "completed":
break
time.sleep(5)

download_url = f"{BASE_URL}/v2/insights/productivity/exports/{export_id}/download?projectIdentifier={PROJECT}&orgIdentifier={ORG}"
file_resp = requests.get(download_url, headers=HEADERS)

with open(f"{export_id}.csv", "wb") as f:
f.write(file_resp.content)

Troubleshooting

Why does exporting Productivity metrics for the entire org sometimes time out?

Exporting Productivity metrics for the entire org from the root node can time out due to the size of large org trees (same limitation as the UI).

To avoid timeouts when exporting, export at the team or group-level instead of requesting the entire org tree at once. Optionally, split large exports into multiple, smaller team-specific API calls.