Bulk Upsert Entities
Bulk upsert entities (create or update) in a single request.
This endpoint:
- Creates new entities for items without
id. - Updates existing entities for items with
id.
It delegates to the shared accountsession bulk infrastructure:
- Manager layer:
GeneralizedManager.bulk_upsert_entities() - DB layer:
Args:
entities_info:
List of entities to upsert. Each item:
- Without id → treated as a create.
- With id → treated as an update for that ID.
override:
Controls update behavior for entities that already have an id
(i.e. the update branch of an upsert). Maps to BulkUpdateMode:
- True → REPLACE: all input fields written, nulls included
(erases existing data). Same as /bulk/update?override=true.
- False → FILL: null inputs are skipped and non-null
inputs only write where the stored value is currently None.
This differs from /bulk/update?override=false (SYNC), which
overwrites existing non-null values. Use FILL when you want to
seed missing fields without touching already-populated ones.
user:
Authenticated user performing the bulk operation.
response:
FastAPI response object, used to set HTTP status to 206 when needed.
Returns:
JSON object with:
- successfulCount (int): number of entities created or updated successfully
- failedCount (int): number of entities that failed
- successfulIds (List[str]): IDs of created/updated entities
- failedIds (List[str]): IDs (when available) or indices of failed entities
- matchedCount (int): number of id-less entities that matched an existing
entity on its natural key, so they were routed to the update branch
rather than created. Counted before the write — read failedIds for
what became of each one.
- matchedIds (List[str]): IDs of the entities those payloads matched
- errors (Dict[str,str]): mapping of index or ID → error description
Query Parameters
- Type: booleanoverride
For entities with IDs, controls update behavior. True = REPLACE (all fields written including nulls). False = FILL (nulls skipped, only empty existing fields filled).
- Type: booleanmatch
_existing For entities without IDs, match each one against an existing entity on its natural key (contacts on email, companies on website domain and name) and update that entity instead of creating a duplicate. Set false to create every id-less entity unconditionally.
Body·Entities Info
- Type: array of EasedBaseModelProperties: 17
Responses
- application/json
- application/json
curl 'https://crm.dreamhub.ai/api/v1/people/bulk/upsert?override=true&match_existing=true' \
--request PUT \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
--data '[
{
"firstName": "John",
"lastName": "Smith",
"companyId": "c-acme123",
"jobTitle": "VP of Engineering",
"phone": "+1-555-123-4567",
"email": "john.smith@acme.com",
"jobFunction": 1,
"deskPhone": "+1-555-123-4567 ext. 123",
"reportsTo": "p-manager123",
"notes": "Prefers email communication",
"address": "123 Main St, San Francisco, CA 94105",
"referenceability": 1,
"status": 1,
"statusReasonText": "Left company",
"statusChangedBy": "u-user123",
"statusChangedAt": "2024-01-15T10:30:00Z",
"additionalProperty": "anything"
}
]'
{
"additionalProperty": "anything"
}
