Batch upsert professors — Create or update up to 1,000 professors in a single request
Create or update up to 1,000 professors in a single request You can now sync professor records in batches using POST /v3/professors/batch-upsert.
This endpoint replaces thousands of sequential requests with a single call, making large-scale imports faster and more reliable for ERP and SIS integrations.
Matching logic
This endpoint performs a batch upsert (create-or-update in one request):
| Identifiers provided | Path | Behaviour |
|---|---|---|
externalReferenceId | Upsert | Update if found, create if not |
professorId | Strict update | Update if found → PROFESSOR_NOT_FOUND if not. No create fallback. |
| Neither | Create | firstName, lastName, email required |
| Both | Rejected | Fails with AMBIGUOUS_PROFESSOR_IDENTIFIER |
Each professor is processed independently, so one failure does not block the rest of the batch.
What’s new
- Batch upsert: create or update up to 1,000 professors per request
- Partial success support: failed records don’t block the rest
- Deterministic behaviour: no implicit restoration or hidden side effects
- Idempotent syncs using your own identifiers
- No cross-record side effects: each professor is processed independently
What to expect
- Returns
200when all professors succeed - Returns
207when some professors fail - Use
inputIndexto map results to your original payload
Overview
Endpoint: POST /v3/professors/batch-upsert
Limits: minimum 1, maximum 1000 professors per request. The endpoint is rate-limited.
{
"professors": [
{
"firstName": "Jean",
"lastName": "Martin",
"email": "[email protected]",
"externalReferenceId": "your-external-reference-id-001",
"externalReferenceType": "external-system-source",
"phone": "+33600000000",
"speciality": "Mathematics",
"tags": ["full-time"]
},
{
"professorId": "gkia42e40c9s6i9",
"firstName": "John",
"lastName": "Doe",
"email": "[email protected]",
"phone": "+33600000000",
"speciality": "Economics",
"tags": ["full-time"]
}
],
"options": {
"onProfessorCreated": {
"sendCredentials": false,
"newPasswordNeeded": false
}
}
}
Response: 200when all professors succeed, or207 when the batch contains both successes and failures.
{
"data": {
"succeeded": [
{
"inputIndex": 0,
"id": "gkia42e40c9s6i9",
"type": "created",
"externalReferenceId": "your-external-reference-id-001"
}
],
"failed": [
{
"inputIndex": 1,
"error": {
"code": "ARCHIVED_PROFESSOR_EXISTS",
"message": "Professor is archived",
"fields": ["professorId"]
}
}
]
},
"meta": {
"total": 2,
"createdCount": 1,
"updatedCount": 0,
"failureCount": 1,
"processedAt": "2026-04-10T10:00:00.000Z"
}
}Professor fields:
Defines the attributes used to create or update a professor record.
Only provided fields are updated (partial update semantics).
| Field | Type | Description |
|---|---|---|
externalReferenceId | string | Your unique identifier for the professor. Used as the create-or-update match key. Max 64 characters. |
externalReferenceType | string | Name of the source system or connector. Max 30 characters. |
professorId | string | Edusign internal professor ID — alternative match key |
firstName | string | Required on create. Max 100 characters. |
lastName | string | Required on create. Max 100 characters. |
email | string | Required on create. Must be unique. Max 255 characters |
phone | string | Accepts null to clear. Max 20 characters |
speciality | string (URL) | Accepts null to clear. Max 255 characters |
tags | string[] | Accepts null to clear. Max 15 tags, each max 35 characters |
Options:
| Field | Default | Description |
|---|---|---|
onProfessorCreated.sendCredentials | false | Sends login credentials by email to newly created professors |
onProfessorCreated.newPasswordNeeded | false | Requires newly created professors to set a password on first login |

