Skip to content

Commit ae6a094

Browse files
authored
SEI-13650 (#11682)
1 parent 9f7aa66 commit ae6a094

File tree

4 files changed

+319
-1
lines changed

4 files changed

+319
-1
lines changed

docs/software-engineering-insights/harness-sei/analytics-and-reporting/_category_.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"label":"Analytics & reporting",
3-
"position": 5,
3+
"position": 4,
44
"collapsible":"true",
55
"collapsed":"true",
66
"className":"default",
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"label":"API",
3+
"position": 5,
4+
"collapsible":"true",
5+
"collapsed":"true",
6+
"className":"default",
7+
"link":{
8+
"type":"generated-index",
9+
"title":"API"
10+
}
11+
}
Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
---
2+
title: Upload and Manage Developer Records Using the Harness SEI API
3+
description: Learn how to use the Harness SEI API to programmatically create and update developer records.
4+
sidebar_label: Upload and Manage Developers
5+
---
6+
7+
## Overview
8+
9+
This page explains how to create and update developer records programmatically, provides best practices for integrating with external systems, and includes troubleshooting information to validate developer data before applying changes.
10+
11+
For a complete list of endpoints and schema definitions, see the [Harness API reference documentation](https://apidocs.harness.io/).
12+
13+
## Before you begin
14+
15+
To call the SEI API, you’ll need:
16+
17+
- A Harness API key
18+
- A Harness account identifier
19+
- A base URL. All API URIs are relative to the SEI service endpoint for your region.
20+
21+
- Prod 1: `https://app.harness.io/prod1/sei/api/`
22+
- Prod 2: `https://app.harness.io/gratis/sei/api/`
23+
- EU: `https://accounts.eu.harness.io/sei/api/`
24+
25+
### Authentication
26+
27+
All Harness SEI APIs require authentication using a Harness API key.
28+
29+
To authenticate:
30+
31+
1. Create a [Harness API key](/docs/platform/automation/api/api-quickstart/).
32+
1. Include the API key in your request header:
33+
34+
```json
35+
curl -X GET \
36+
"https://app.harness.io/gateway/sei/api/v2/developers/schema" \
37+
-H "x-api-key: <YOUR_API_KEY>" \
38+
```
39+
40+
## Manage developer records
41+
42+
The Harness SEI API enables programmatic management of developer records. You can use the API to automate updates by writing scripts or jobs that trigger record changes whenever your source of truth (such as an HR system) changes.
43+
44+
This reduces manual edits, lowers the risk of errors, and ensures developer data stays accurate and consistent for productivity and DORA metrics.
45+
46+
### Initial setup (Upload and save)
47+
48+
```mermaid
49+
graph LR
50+
A["CSV File"] --> B["POST /v2/developers/upload"]
51+
B --> C["Preview & Field Mapping"]
52+
C --> D["POST /v2/developers/uploads/{uploadId}/save"]
53+
D --> E["Developers Saved"]
54+
E --> F["Other APIs Available"]
55+
56+
%% Define classes
57+
class A csvFile;
58+
class C preview;
59+
class D developersSaved;
60+
class E developersSaved;
61+
62+
%% Styling
63+
classDef csvFile fill:#fff9c4,stroke:#333,stroke-width:1px; %% pale yellow
64+
classDef preview fill:#bbdefb,stroke:#333,stroke-width:1px; %% pale blue
65+
classDef developersSaved fill:#c8e6c9,stroke:#333,stroke-width:1px; %% pale green
66+
```
67+
68+
The developer schema and baseline data must first be established using the upload and save workflow:
69+
70+
1. `POST /v2/developers/upload`: Upload a CSV file containing developer data (CSV only, cannot be JSON), which returns an upload preview with field mappings.
71+
1. `POST /v2/developers/uploads/{uploadId}/save`: Configure field mappings (such as `NAME`, `EMAIL`, `MANAGER_EMAIL`) and save developers into the system. You must complete this step before using other developer management APIs.
72+
73+
:::danger
74+
Reupload, approve, and upsert operations will return `412 Precondition Failed` if attempted before completing this initial setup.
75+
:::
76+
77+
### Bulk update (Re-upload & approve)
78+
79+
```mermaid
80+
graph LR
81+
A["New CSV File"] --> B["POST /v2/developers/reupload"]
82+
B --> C["Review Changes"]
83+
C --> D["POST /v2/developers/uploads/{uploadId}/approve"]
84+
D --> E["Changes Activated"]
85+
86+
%% Define classes
87+
class A csvFile;
88+
class C preview;
89+
class D developersSaved;
90+
class E developersSaved;
91+
92+
%% Styling
93+
classDef csvFile fill:#fff9c4,stroke:#333,stroke-width:1px; %% pale yellow
94+
classDef preview fill:#bbdefb,stroke:#333,stroke-width:1px; %% pale blue
95+
classDef developersSaved fill:#c8e6c9,stroke:#333,stroke-width:1px; %% pale green
96+
```
97+
98+
To update existing developer data with a new CSV file, the initial upload/save must be completed first.
99+
100+
1. `POST /v2/developers/reupload`: Upload a new CSV file with updated developer data. This automatically uses existing field mappings and returns review data showing changes.
101+
1. `POST /v2/developers/uploads/{uploadId}/approve`: Review and approve the changes, and activate the new developer dataset.
102+
103+
## Developer endpoints
104+
105+
| Action | Endpoint | Usage |
106+
|:---:|:---:|:---:|
107+
| Reupload developer records | `POST /v2/developers/reupload` | Reupload a CSV file with review data for approval workflow. CSV file only. |
108+
| Approve developer records | `POST /v2/developers/uploads/{uploadId}/approve` | Approve developers reupload and activate the changes. |
109+
| Upsert developers | `PATCH /v2/developers` | Add new developers or update existing ones. JSON only, no two-step approval process. |
110+
| Delete developers | `DELETE /v2/developers` | Delete developers by their email addresses. |
111+
| Search / list developers | `POST /v2/developers/list` | Search developers with filtering and sorting options. Search by attributes (key-value pair like "department":"Engineering", name). |
112+
| Get developer schema | `GET /v2/developers/schema` | Get the latest developer field mappings (schema) for the account. Retrieve the schema for developer records and field mappings. |
113+
| Download developer data | `GET /v2/developers/download` | Download a CSV file containing all developers currently in the system for auditing or sync back to third-party systems. |
114+
115+
### cURL commands
116+
117+
#### Reupload developer records (`POST /v2/developers/reupload`)
118+
119+
```json
120+
curl -X 'POST' \
121+
'https://app.harness.io/prod1/sei/api/v2/developers/reupload?fileType=CSV' \
122+
-H "accept: application/json" \
123+
-H "Content-Type: multipart/form-data" \
124+
-F "file=@Sample_CSV_for_Importing_Developers.csv;type=text/csv"
125+
```
126+
127+
#### Approve developer records (`POST /v2/developers/uploads/{uploadId}/approve`)
128+
129+
```json
130+
curl -X 'POST' \
131+
'https://app.harness.io/prod1/sei/api/v2/developers/uploads/<YOUR_UPLOAD_ID>/approve' \
132+
-H 'accept: */*' \
133+
-d ''
134+
```
135+
136+
#### Upsert developers (`PATCH /v2/developers`)
137+
138+
```json
139+
curl -X 'PATCH' \
140+
'https://app.harness.io/prod1/sei/api/v2/developers' \
141+
-H 'accept: */*' \
142+
-H 'Content-Type: application/json' \
143+
-d '[
144+
{
145+
"<NEW_RECORD>": "string",
146+
"<NEW_RECORD>": "string",
147+
"<NEW_RECORD>": "string"
148+
}
149+
```
150+
151+
#### Delete developers (`DELETE /v2/developers`)
152+
153+
```json
154+
curl -X 'DELETE' \
155+
'https://app.harness.io/prod1/sei/api/v2/developers' \
156+
-H 'accept: */*' \
157+
-H 'Content-Type: application/json' \
158+
-d '{
159+
"emails": [
160+
161+
162+
]
163+
```
164+
165+
#### Search/list developers (`POST /v2/developers/list`)
166+
167+
```json
168+
curl -X 'POST' \
169+
'https://app.harness.io/prod1/sei/api/v2/developers/list
170+
pageIndex=<INTEGER>&pageSize=<INTEGER>' \
171+
-H 'accept: application/json' \
172+
-H 'Content-Type: application/json' \
173+
-d '{
174+
"sortOrder": "asc",
175+
"searchKey": "string",
176+
"searchValue": "string",
177+
"sortKey": "string",
178+
"developerRefIds": [
179+
1073741824
180+
]
181+
```
182+
183+
#### Get developer schema (`GET /v2/developers/schema`)
184+
185+
```json
186+
curl -X 'GET' \
187+
'https://app.harness.io/prod1/sei/api/v2/developers/schema' \
188+
-H 'accept: application/json' \
189+
```
190+
191+
#### Download developer data (`GET /v2/developers/download`)
192+
193+
```json
194+
curl -X 'GET' \
195+
'https://app.harness.io/prod1/sei/api/v2/developers/download' \
196+
-H 'accept: text/csv' \
197+
```
198+
199+
## Sync developer records
200+
201+
You have two options for syncing developer records with Harness SEI APIs:
202+
203+
1. **Event-Driven Sync** (JSON, small updates): This is best for event-driven syncs, such as when a new hire webhook triggers an update.
204+
205+
:::danger
206+
Upsert will return `412 Precondition Failed` if the [initial setup](#initial-setup-upload-and-save) hasn’t been completed.
207+
:::
208+
209+
- Fetch developer records from an external source such as an HR system.
210+
- Call `PATCH /v2/developers` to insert or update the records.
211+
- Validate using `POST /v2/developers/list`.
212+
213+
1. **Scheduled Sync** (CSV, bulk updates): This is best for nightly or weekly HR exports. CSV is required for upload and save, and JSON is not supported.
214+
215+
- Upload a CSV file using `POST /v2/developers/reupload` and `POST /v2/developers/uploads/{uploadId}/approve` (response includes a preview and validation).
216+
- Review preview or validation errors. Correct upstream as needed.
217+
- Save developers using `POST /v2/developers/uploads/{uploadId}/save` to commit to the system.
218+
- Export the latest developer list using `GET /v2/developers/download` for auditing.
219+
220+
For automated syncs, Harness recommends running them daily in high-churn orgs and weekly in stable ones, with on-demand syncs when HR system changes occur. Always preview and audit changes, validate errors early, and apply business rules for invalid rows.
221+
222+
## Example use case
223+
224+
A nightly job queries an HRIS system for all active employees in engineering.
225+
226+
```mermaid
227+
graph LR
228+
A["Query HRIS for active engineers"] --> B["Upload CSV: POST /v2/developers/upload"]
229+
B --> C["Preview & Validation"]
230+
C --> D["Save Developers: POST /v2/developers/uploads/{uploadId}/save"]
231+
D --> E["Developers Saved / Ready for Other APIs"]
232+
E --> F["Optional: Export CSV via GET /v2/developers/download"]
233+
234+
%% Define classes
235+
class A hrisQuery;
236+
class B csvFile;
237+
class C preview;
238+
class D csvFile;
239+
class E developersSaved;
240+
class F csvFile;
241+
242+
%% Styling
243+
classDef hrisQuery fill:#ffebee,stroke:#e57373,stroke-width:1px; %% pale red
244+
classDef csvFile fill:#fff9c4,stroke:#333,stroke-width:1px; %% pale yellow
245+
classDef preview fill:#bbdefb,stroke:#333,stroke-width:1px; %% pale blue
246+
classDef developersSaved fill:#c8e6c9,stroke:#333,stroke-width:1px; %% pale green
247+
```
248+
249+
1. Upload a CSV file containing developer data using `POST /v2/developers/upload`. This returns a preview with field mappings and validation errors.
250+
1. Check for validation errors in the preview (e.g. `REQUIRED_FIELD_MISSING` or `DUPLICATE_EMAIL`) and correct errors upstream in the CSV file if necessary.
251+
1. Commit the uploaded developer data into the system using `POST /v2/developers/uploads/{uploadId}/save`. The initial setup must be completed before using other APIs, otherwise upsert, reupload, or approve operations will return `412 Precondition Failed`.
252+
1. Optionally, export the current developer list using `GET /v2/developers/download` for auditing or syncing with external systems.
253+
254+
## Troubleshooting
255+
256+
Developer operations (`save`, `upsert`, `delete`, and `reupload`) perform comprehensive validation and return structured error responses when validation fails.
257+
258+
Validation errors help identify and resolve issues with CSV uploads, field mappings, and developer record data before any changes are applied.
259+
260+
### Error types
261+
262+
| Error Type | When it Occurs | Details |
263+
|:---:|:---:|:---:|
264+
| `REQUIRED_FIELD_MISSING` | A required field is missing from the CSV upload or field mappings. | Required fields include `name`, `email`, and `manager_email` (if configured), as well as any fields used in org tree filters or group-by configurations. Triggered during file upload when mappings don’t include required fields. |
265+
| `REQUIRED_VALUE_MISSING` | Required fields have empty or blank values in developer records. | Applies to `name` and `email` (always required). Triggered when any developer record has empty/null values for these fields. |
266+
| `DUPLICATE_EMAIL` | Multiple developer records share the same email address. | Each developer must have a unique email. Applies to all developer operations (`save`, `upsert`, `delete`). |
267+
| `CIRCULAR_REFERENCE` | Manager-employee relationships form circular references. | Example: A reports to B, and B reports to A. Detected through graph traversal of manager-employee relationships. Prevents infinite loops in the org hierarchy. |
268+
| `MANAGER_EMAIL_MISSING_IN_DEVELOPER_EMAILS` | A developer’s `manager_email` value doesn’t exist in the dataset. | Manager email can be empty, but if provided, it must match an existing developer’s email. Ensures all managers are also developers. |
269+
| `MISSING_NAME_OR_EMAIL_OR_MANAGER_EMAIL_FIELD_MAPPING` | Essential field mappings (`NAME`, `EMAIL`, or `MANAGER_EMAIL`) are missing from field configuration. | Triggered during save when required field types are not mapped to CSV columns. Prevents saving when core identification fields are undefined. |
270+
| `INVALID_CSV` | The uploaded CSV file format is invalid or corrupted. | Triggered during upload when parsing fails. Causes include malformed structure, encoding issues, or file corruption. |
271+
| `EMPTY_CSV` | The uploaded CSV file contains no data rows. | Triggered when the file has only headers or is entirely empty. Prevents processing of empty datasets. |
272+
| `BLANK_CSV_COLUMN_NAME` | The CSV contains columns with blank or empty header names. | Triggered during upload when headers are missing or contain only whitespace. Ensures all columns have valid names for mapping. |
273+
274+
### Error response structure
275+
276+
All validation errors are returned in the following structure:
277+
278+
```json
279+
{
280+
"status": "FAILURE",
281+
"errors": [
282+
{
283+
"errorType": "ERROR_TYPE_NAME",
284+
"fieldName": "field_name_or_null",
285+
"errorDeveloperCount": 10,
286+
"sampleErrorDevelopers": [
287+
{
288+
"field1": "value1",
289+
"field2": "value2"
290+
}
291+
]
292+
}
293+
]
294+
}
295+
```
296+
297+
- `sampleErrorDevelopers` is limited to a partial list of records per error type.
298+
- `errorDeveloperCount` shows the total number of records affected.
299+
300+
Multiple error types can be returned simultaneously and validation occurs before any data is saved to prevent partial updates.

sidebars.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3488,6 +3488,13 @@ const sidebars: SidebarsConfig = {
34883488
{ type: 'autogenerated', dirName: 'software-engineering-insights/harness-sei/analytics-and-reporting' },
34893489
],
34903490
},
3491+
{
3492+
type: 'category',
3493+
label: 'API',
3494+
items: [
3495+
{ type: 'autogenerated', dirName: 'software-engineering-insights/harness-sei/api' },
3496+
],
3497+
},
34913498
],
34923499
},
34933500
{

0 commit comments

Comments
 (0)