> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.trebellar.app/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.trebellar.app/_mcp/server. # Batch Create/Update People POST https://api.trebellar.app/api/v2/people/batch/upsert Content-Type: application/json Create new people or update existing employee records in a single batch operation. Use this for HR system integrations, bulk imports, or synchronized employee data updates. Each person record can include employment details, contact information, and initial group assignments. Existing people are matched by ID and updated; new records without IDs are created. Reference: https://docs.trebellar.app/api-reference/api-resources/people/upsert-people-batch ## Authentication - `X-Trebellar-Api-Key` header (required) — API Key authentication via header - `Authorization` header (bearer token, required) — Bearer authentication of the form `Bearer `, where token is your auth token. ## Request ### Body (application/json) This endpoint expects an UpsertPeopleBatchRequest. - `people` (list of PeopleInput, required) ## Response ### 200 All people records processed successfully - existing employees updated and new employees created - `data` (list of People, required) ## Errors ### 400 Bad Request Error Bad Request Error - `code` (double, required) - `message` (string, required) - `error` (string, optional) - `details` (map from string to any, optional) ### 500 Internal Server Error Internal Server Error - `code` (double, required) - `message` (string, required) - `error` (string, optional) - `details` (map from string to any, optional) ## Types ### PeopleInput Employee record for creation or update operations - `id` (string, optional) - `externalId` (string, optional) - `assetId` (string, optional) — A unique identifier for an asset, typically prefixed by its type - `name` (string, optional) - `hireDate` (double, optional) - `employmentStatus` (enum, optional) - Allowed values: `active`, `inactive` - `terminationDate` (double, optional) - `address` (PeopleAddress, optional) — Employee address information for contact and commute analysis - `properties` (map from string to any, optional) ### People Complete employee record with system timestamps - `id` (string, required) - `groups` (list of PeopleGroup, required) - `externalId` (string, optional) - `assetId` (string, optional) — A unique identifier for an asset, typically prefixed by its type - `name` (string, optional) - `hireDate` (double, optional) - `employmentStatus` (enum, optional) - Allowed values: `active`, `inactive` - `terminationDate` (double, optional) - `address` (PeopleAddress, optional) — Employee address information for contact and commute analysis - `properties` (map from string to any, optional) - `createdAt` (PeopleCreatedAt, optional) - `updatedAt` (PeopleUpdatedAt, optional) ### PeopleAddress Employee address information for contact and commute analysis - `raw` (string, optional) - `postalCode` (string, optional) - `streetName` (string, optional) - `city` (string, optional) - `state` (string, optional) - `countryIso` (string, optional) ### PeopleGroup Complete people group record with hierarchical path - `id` (string, required) - `name` (string, required) - `status` (enum, required) - Allowed values: `PEOPLE_GROUP_STATUS_UNKNOWN`, `PEOPLE_GROUP_STATUS_ACTIVE`, `PEOPLE_GROUP_STATUS_INACTIVE`, `PEOPLE_GROUP_STATUS_ARCHIVED` - `path` (string, optional) - `parentId` (string, optional) - `avatarUrl` (string, optional) - `description` (string, optional) - `properties` (PeopleGroupPropertiesOutput, optional) — Custom properties for group visualization and categorization - `externalId` (string, optional) ### PeopleCreatedAt ### PeopleUpdatedAt ### PeopleGroupPropertiesOutput Custom properties for group visualization and categorization - `color` (string, optional) ## Examples **Request** ```json { "people": [ { "externalId": "EMP001", "name": "Jane Smith", "employmentStatus": "active" }, { "id": "emp_existing_123", "name": "John Updated", "employmentStatus": "active" } ] } ``` **Response** ```json { "data": [ { "id": "string", "groups": [ { "id": "string", "name": "string", "status": "PEOPLE_GROUP_STATUS_UNKNOWN", "path": "string", "parentId": "string", "avatarUrl": "string", "description": "string", "properties": { "color": "#FF5722" }, "externalId": "string" } ], "externalId": "string", "assetId": "st_sf_tower_01", "name": "string", "hireDate": 1.1, "employmentStatus": "active", "terminationDate": 1.1, "address": { "raw": "123 Main St, Apt 4B, San Francisco, CA 94105", "postalCode": "94105", "streetName": "Main St", "city": "San Francisco", "state": "CA", "countryIso": "US" }, "properties": {}, "createdAt": "string", "updatedAt": "string" } ] } ``` **SDK Code** ```typescript import { TrebellarApiClient } from "@trebellar/api-sdk"; async function main() { const client = new TrebellarApiClient({ apiKey: "YOUR_API_KEY_HERE", }); await client.people.upsertPeopleBatch({ people: [ { externalId: "EMP001", name: "Jane Smith", employmentStatus: "active", }, { id: "emp_existing_123", name: "John Updated", employmentStatus: "active", }, ], }); } main(); ``` ```python from trebellar import TrebellarApi, PeopleInput client = TrebellarApi( api_key="YOUR_API_KEY_HERE", ) client.people.upsert_people_batch( people=[ PeopleInput( external_id="EMP001", name="Jane Smith", employment_status="active", ), PeopleInput( id="emp_existing_123", name="John Updated", employment_status="active", ) ], ) ``` ```go package main import ( "fmt" "strings" "net/http" "io" ) func main() { url := "https://api.trebellar.app/api/v2/people/batch/upsert" payload := strings.NewReader("{\n \"people\": [\n {\n \"externalId\": \"EMP001\",\n \"name\": \"Jane Smith\",\n \"employmentStatus\": \"active\"\n },\n {\n \"id\": \"emp_existing_123\",\n \"name\": \"John Updated\",\n \"employmentStatus\": \"active\"\n }\n ]\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("X-Trebellar-Api-Key", "") req.Header.Add("Content-Type", "application/json") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```ruby require 'uri' require 'net/http' url = URI("https://api.trebellar.app/api/v2/people/batch/upsert") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Post.new(url) request["X-Trebellar-Api-Key"] = '' request["Content-Type"] = 'application/json' request.body = "{\n \"people\": [\n {\n \"externalId\": \"EMP001\",\n \"name\": \"Jane Smith\",\n \"employmentStatus\": \"active\"\n },\n {\n \"id\": \"emp_existing_123\",\n \"name\": \"John Updated\",\n \"employmentStatus\": \"active\"\n }\n ]\n}" response = http.request(request) puts response.read_body ``` ```java import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.post("https://api.trebellar.app/api/v2/people/batch/upsert") .header("X-Trebellar-Api-Key", "") .header("Content-Type", "application/json") .body("{\n \"people\": [\n {\n \"externalId\": \"EMP001\",\n \"name\": \"Jane Smith\",\n \"employmentStatus\": \"active\"\n },\n {\n \"id\": \"emp_existing_123\",\n \"name\": \"John Updated\",\n \"employmentStatus\": \"active\"\n }\n ]\n}") .asString(); ``` ```php request('POST', 'https://api.trebellar.app/api/v2/people/batch/upsert', [ 'body' => '{ "people": [ { "externalId": "EMP001", "name": "Jane Smith", "employmentStatus": "active" }, { "id": "emp_existing_123", "name": "John Updated", "employmentStatus": "active" } ] }', 'headers' => [ 'Content-Type' => 'application/json', 'X-Trebellar-Api-Key' => '', ], ]); echo $response->getBody(); ``` ```csharp using RestSharp; var client = new RestClient("https://api.trebellar.app/api/v2/people/batch/upsert"); var request = new RestRequest(Method.POST); request.AddHeader("X-Trebellar-Api-Key", ""); request.AddHeader("Content-Type", "application/json"); request.AddParameter("application/json", "{\n \"people\": [\n {\n \"externalId\": \"EMP001\",\n \"name\": \"Jane Smith\",\n \"employmentStatus\": \"active\"\n },\n {\n \"id\": \"emp_existing_123\",\n \"name\": \"John Updated\",\n \"employmentStatus\": \"active\"\n }\n ]\n}", ParameterType.RequestBody); IRestResponse response = client.Execute(request); ``` ```swift import Foundation let headers = [ "X-Trebellar-Api-Key": "", "Content-Type": "application/json" ] let parameters = ["people": [ [ "externalId": "EMP001", "name": "Jane Smith", "employmentStatus": "active" ], [ "id": "emp_existing_123", "name": "John Updated", "employmentStatus": "active" ] ]] as [String : Any] let postData = JSONSerialization.data(withJSONObject: parameters, options: []) let request = NSMutableURLRequest(url: NSURL(string: "https://api.trebellar.app/api/v2/people/batch/upsert")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0) request.httpMethod = "POST" request.allHTTPHeaderFields = headers request.httpBody = postData as Data let session = URLSession.shared let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in if (error != nil) { print(error as Any) } else { let httpResponse = response as? HTTPURLResponse print(httpResponse) } }) dataTask.resume() ```