> For the complete documentation index, see [llms.txt](https://guide.fariaedu.com/integrations-portal/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://guide.fariaedu.com/integrations-portal/schoolsbuddy/public-rest-apis/staff.md).

# Staff

## GET /api/v1/Staff

> Gets a paginated list of staff members

```json
{"openapi":"3.0.4","info":{"title":"SchoolsBuddy Public API","version":"1.0"},"tags":[{"name":"Staff"}],"servers":[{"url":"https://publicapi-eu.schoolsbuddy.net","description":"EMEA Public Api server"},{"url":"https://publicapi-asia.schoolsbuddy.net","description":"Asia Public Api server"},{"url":"https://publicapi-us.schoolsbuddy.net","description":"US Public Api server"},{"url":"https://publicapi.schoolsbuddy.cn","description":"China Public Api server"},{"url":"https://identity-eu.schoolsbuddy.net","description":"EMEA Identity server"},{"url":"https://identity-asia.schoolsbuddy.net","description":"Asia Identity server"},{"url":"https://identity-us.schoolsbuddy.net","description":"US Identity server"},{"url":"https://accounts.schoolsbuddy.cn","description":"China Identity server"}],"security":[{"Bearer":[]}],"components":{"securitySchemes":{"Bearer":{"type":"apiKey","description":"Type \"Bearer\" followed by a space and a token.","name":"Authorization","in":"header"}},"schemas":{"StaffDataDtoListPagedStaffFilterResponseDto":{"type":"object","properties":{"isSuccess":{"type":"boolean"},"errors":{"type":"array","items":{"type":"string"},"nullable":true},"messageTranslationParameters":{"nullable":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/StaffDataDto"},"nullable":true},"pageNumber":{"type":"integer","format":"int32"},"pageSize":{"type":"integer","format":"int32"},"firstPage":{"type":"string","format":"uri","nullable":true},"lastPage":{"type":"string","format":"uri","nullable":true},"totalPages":{"type":"integer","format":"int32"},"totalRecords":{"type":"integer","format":"int32"},"nextPage":{"type":"string","format":"uri","nullable":true},"previousPage":{"type":"string","format":"uri","nullable":true},"baseUri":{"type":"string","format":"uri","nullable":true},"searchParameters":{"type":"array","items":{"$ref":"#/components/schemas/StringStringKeyValuePair"},"nullable":true}},"additionalProperties":false},"StaffDataDto":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"organisationId":{"type":"integer","format":"int32","nullable":true},"staffId":{"type":"string","nullable":true},"firstName":{"type":"string","nullable":true},"lastName":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"role":{"$ref":"#/components/schemas/PublicApiOrganisationRole"},"createdAtUtc":{"type":"string","format":"date-time"},"updatedAtUtc":{"type":"string","format":"date-time"},"isArchived":{"type":"boolean"},"updatable":{"type":"boolean"}},"additionalProperties":false},"PublicApiOrganisationRole":{"enum":["Staff","ExternalCoach","BusMonitor"],"type":"string"},"StringStringKeyValuePair":{"type":"object","properties":{"key":{"type":"string","nullable":true},"value":{"type":"string","nullable":true}},"additionalProperties":false},"ErrorResponse":{"type":"object","properties":{"code":{"type":"string","description":"Gets or sets the machine-readable error code (e.g.\n`VALIDATION_FAILED`, `RESOURCE_NOT_FOUND`,\n`INTERNAL_ERROR`) per cross-cutting-design.md §5.1.","nullable":true},"error":{"type":"string","description":"Gets or sets the human-readable error message.","nullable":true}},"additionalProperties":false,"description":"Structured body for 4xx / 5xx responses on the new Public API surface:\na machine-readable SchoolsBuddy.PublicAPI.Models.ErrorResponse.Code plus a human-readable\nSchoolsBuddy.PublicAPI.Models.ErrorResponse.Error. See cross-cutting-design.md §5.3. This is additive —\nexisting endpoints continue returning their legacy plain-string /\nModelState shapes until migrated by their per-controller ticket."}}},"paths":{"/api/v1/Staff":{"get":{"tags":["Staff"],"summary":"Gets a paginated list of staff members","parameters":[{"name":"IncludeArchived","in":"query","schema":{"type":"boolean"}},{"name":"Search","in":"query","schema":{"maxLength":200,"type":"string"}},{"name":"PageNumber","in":"query","schema":{"maximum":2147483647,"minimum":1,"type":"integer","format":"int32"}},{"name":"PageSize","in":"query","schema":{"maximum":2000,"minimum":1,"type":"integer","format":"int32"}},{"name":"OrganisationIds","in":"query","schema":{"type":"array","items":{"type":"integer","format":"int32"}}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StaffDataDtoListPagedStaffFilterResponseDto"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## POST /api/v1/Staff

> Create a new staff member. \`isArchived\` is not part of the create\
> contract (BP2) — a staff member is always created active and any value\
> sent for it is silently ignored.

```json
{"openapi":"3.0.4","info":{"title":"SchoolsBuddy Public API","version":"1.0"},"tags":[{"name":"Staff"}],"servers":[{"url":"https://publicapi-eu.schoolsbuddy.net","description":"EMEA Public Api server"},{"url":"https://publicapi-asia.schoolsbuddy.net","description":"Asia Public Api server"},{"url":"https://publicapi-us.schoolsbuddy.net","description":"US Public Api server"},{"url":"https://publicapi.schoolsbuddy.cn","description":"China Public Api server"},{"url":"https://identity-eu.schoolsbuddy.net","description":"EMEA Identity server"},{"url":"https://identity-asia.schoolsbuddy.net","description":"Asia Identity server"},{"url":"https://identity-us.schoolsbuddy.net","description":"US Identity server"},{"url":"https://accounts.schoolsbuddy.cn","description":"China Identity server"}],"security":[{"Bearer":[]}],"components":{"securitySchemes":{"Bearer":{"type":"apiKey","description":"Type \"Bearer\" followed by a space and a token.","name":"Authorization","in":"header"}},"schemas":{"StaffCreateRequestDto":{"type":"object","properties":{"staffId":{"maxLength":50,"type":"string","nullable":true},"title":{"maxLength":10,"type":"string","nullable":true},"lastName":{"maxLength":50,"type":"string","nullable":true},"firstName":{"maxLength":50,"type":"string","nullable":true},"email":{"maxLength":250,"type":"string","nullable":true},"onlineMeetingId":{"maxLength":250,"type":"string","nullable":true},"mobilePhone":{"maxLength":250,"type":"string","nullable":true},"phoneNumber":{"maxLength":250,"type":"string","nullable":true},"updateable":{"type":"boolean"},"role":{"$ref":"#/components/schemas/PublicApiOrganisationRole"}},"additionalProperties":false},"PublicApiOrganisationRole":{"enum":["Staff","ExternalCoach","BusMonitor"],"type":"string"},"StaffCoreDto":{"type":"object","properties":{"id":{"type":"integer","format":"int32","nullable":true},"organisationId":{"type":"integer","format":"int32","nullable":true},"staffId":{"type":"string","nullable":true},"title":{"type":"string","nullable":true},"lastName":{"type":"string","nullable":true},"firstName":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"role":{"$ref":"#/components/schemas/PublicApiOrganisationRole"},"onlineMeetingId":{"type":"string","nullable":true},"isArchived":{"type":"boolean"},"mobilePhone":{"type":"string","nullable":true},"phoneNumber":{"type":"string","nullable":true},"createdAtUtc":{"type":"string","format":"date-time","nullable":true},"updatedAtUtc":{"type":"string","format":"date-time","nullable":true},"updatable":{"type":"boolean"}},"additionalProperties":false},"ErrorResponse":{"type":"object","properties":{"code":{"type":"string","description":"Gets or sets the machine-readable error code (e.g.\n`VALIDATION_FAILED`, `RESOURCE_NOT_FOUND`,\n`INTERNAL_ERROR`) per cross-cutting-design.md §5.1.","nullable":true},"error":{"type":"string","description":"Gets or sets the human-readable error message.","nullable":true}},"additionalProperties":false,"description":"Structured body for 4xx / 5xx responses on the new Public API surface:\na machine-readable SchoolsBuddy.PublicAPI.Models.ErrorResponse.Code plus a human-readable\nSchoolsBuddy.PublicAPI.Models.ErrorResponse.Error. See cross-cutting-design.md §5.3. This is additive —\nexisting endpoints continue returning their legacy plain-string /\nModelState shapes until migrated by their per-controller ticket."}}},"paths":{"/api/v1/Staff":{"post":{"tags":["Staff"],"summary":"Create a new staff member. `isArchived` is not part of the create\ncontract (BP2) — a staff member is always created active and any value\nsent for it is silently ignored.","parameters":[{"name":"organisationId","in":"query","description":"The organisation to create the staff member in — required when the client has access to multiple organisations","schema":{"type":"integer","format":"int32"}}],"requestBody":{"description":"The create request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StaffCreateRequestDto"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StaffCoreDto"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## GET /api/v1/Staff/{id}

> Get staff by Id (full details).

```json
{"openapi":"3.0.4","info":{"title":"SchoolsBuddy Public API","version":"1.0"},"tags":[{"name":"Staff"}],"servers":[{"url":"https://publicapi-eu.schoolsbuddy.net","description":"EMEA Public Api server"},{"url":"https://publicapi-asia.schoolsbuddy.net","description":"Asia Public Api server"},{"url":"https://publicapi-us.schoolsbuddy.net","description":"US Public Api server"},{"url":"https://publicapi.schoolsbuddy.cn","description":"China Public Api server"},{"url":"https://identity-eu.schoolsbuddy.net","description":"EMEA Identity server"},{"url":"https://identity-asia.schoolsbuddy.net","description":"Asia Identity server"},{"url":"https://identity-us.schoolsbuddy.net","description":"US Identity server"},{"url":"https://accounts.schoolsbuddy.cn","description":"China Identity server"}],"security":[{"Bearer":[]}],"components":{"securitySchemes":{"Bearer":{"type":"apiKey","description":"Type \"Bearer\" followed by a space and a token.","name":"Authorization","in":"header"}},"schemas":{"StaffCoreDto":{"type":"object","properties":{"id":{"type":"integer","format":"int32","nullable":true},"organisationId":{"type":"integer","format":"int32","nullable":true},"staffId":{"type":"string","nullable":true},"title":{"type":"string","nullable":true},"lastName":{"type":"string","nullable":true},"firstName":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"role":{"$ref":"#/components/schemas/PublicApiOrganisationRole"},"onlineMeetingId":{"type":"string","nullable":true},"isArchived":{"type":"boolean"},"mobilePhone":{"type":"string","nullable":true},"phoneNumber":{"type":"string","nullable":true},"createdAtUtc":{"type":"string","format":"date-time","nullable":true},"updatedAtUtc":{"type":"string","format":"date-time","nullable":true},"updatable":{"type":"boolean"}},"additionalProperties":false},"PublicApiOrganisationRole":{"enum":["Staff","ExternalCoach","BusMonitor"],"type":"string"},"ErrorResponse":{"type":"object","properties":{"code":{"type":"string","description":"Gets or sets the machine-readable error code (e.g.\n`VALIDATION_FAILED`, `RESOURCE_NOT_FOUND`,\n`INTERNAL_ERROR`) per cross-cutting-design.md §5.1.","nullable":true},"error":{"type":"string","description":"Gets or sets the human-readable error message.","nullable":true}},"additionalProperties":false,"description":"Structured body for 4xx / 5xx responses on the new Public API surface:\na machine-readable SchoolsBuddy.PublicAPI.Models.ErrorResponse.Code plus a human-readable\nSchoolsBuddy.PublicAPI.Models.ErrorResponse.Error. See cross-cutting-design.md §5.3. This is additive —\nexisting endpoints continue returning their legacy plain-string /\nModelState shapes until migrated by their per-controller ticket."}}},"paths":{"/api/v1/Staff/{id}":{"get":{"tags":["Staff"],"summary":"Get staff by Id (full details).","parameters":[{"name":"id","in":"path","description":"The staff member id (Person.Id)","required":true,"schema":{"type":"integer","format":"int32"}},{"name":"organisationId","in":"query","description":"The organisation to look the staff member up in — required when the client has access to multiple organisations","schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StaffCoreDto"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## PUT /api/v1/Staff/{id}

> Partially updates a staff member — omitted (or explicitly null) fields\
> preserve their stored values (BP10 / §3.7e, D14). Sending\
> \`isArchived\` archives or unarchives; omitting it leaves the\
> archive state alone. An archived staff member accepts only a PUT carrying\
> \`isArchived: false\`. The response is the staff member as stored after\
> the write — including when the PUT has just archived it.

```json
{"openapi":"3.0.4","info":{"title":"SchoolsBuddy Public API","version":"1.0"},"tags":[{"name":"Staff"}],"servers":[{"url":"https://publicapi-eu.schoolsbuddy.net","description":"EMEA Public Api server"},{"url":"https://publicapi-asia.schoolsbuddy.net","description":"Asia Public Api server"},{"url":"https://publicapi-us.schoolsbuddy.net","description":"US Public Api server"},{"url":"https://publicapi.schoolsbuddy.cn","description":"China Public Api server"},{"url":"https://identity-eu.schoolsbuddy.net","description":"EMEA Identity server"},{"url":"https://identity-asia.schoolsbuddy.net","description":"Asia Identity server"},{"url":"https://identity-us.schoolsbuddy.net","description":"US Identity server"},{"url":"https://accounts.schoolsbuddy.cn","description":"China Identity server"}],"security":[{"Bearer":[]}],"components":{"securitySchemes":{"Bearer":{"type":"apiKey","description":"Type \"Bearer\" followed by a space and a token.","name":"Authorization","in":"header"}},"schemas":{"StaffUpdateRequestDto":{"type":"object","properties":{"staffId":{"maxLength":50,"type":"string","nullable":true},"title":{"maxLength":10,"type":"string","nullable":true},"lastName":{"maxLength":50,"type":"string","nullable":true},"firstName":{"maxLength":50,"type":"string","nullable":true},"email":{"maxLength":250,"type":"string","nullable":true},"onlineMeetingId":{"maxLength":250,"type":"string","nullable":true},"mobilePhone":{"maxLength":250,"type":"string","nullable":true},"phoneNumber":{"maxLength":250,"type":"string","nullable":true},"isArchived":{"type":"boolean","nullable":true}},"additionalProperties":false},"StaffCoreDto":{"type":"object","properties":{"id":{"type":"integer","format":"int32","nullable":true},"organisationId":{"type":"integer","format":"int32","nullable":true},"staffId":{"type":"string","nullable":true},"title":{"type":"string","nullable":true},"lastName":{"type":"string","nullable":true},"firstName":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"role":{"$ref":"#/components/schemas/PublicApiOrganisationRole"},"onlineMeetingId":{"type":"string","nullable":true},"isArchived":{"type":"boolean"},"mobilePhone":{"type":"string","nullable":true},"phoneNumber":{"type":"string","nullable":true},"createdAtUtc":{"type":"string","format":"date-time","nullable":true},"updatedAtUtc":{"type":"string","format":"date-time","nullable":true},"updatable":{"type":"boolean"}},"additionalProperties":false},"PublicApiOrganisationRole":{"enum":["Staff","ExternalCoach","BusMonitor"],"type":"string"},"ErrorResponse":{"type":"object","properties":{"code":{"type":"string","description":"Gets or sets the machine-readable error code (e.g.\n`VALIDATION_FAILED`, `RESOURCE_NOT_FOUND`,\n`INTERNAL_ERROR`) per cross-cutting-design.md §5.1.","nullable":true},"error":{"type":"string","description":"Gets or sets the human-readable error message.","nullable":true}},"additionalProperties":false,"description":"Structured body for 4xx / 5xx responses on the new Public API surface:\na machine-readable SchoolsBuddy.PublicAPI.Models.ErrorResponse.Code plus a human-readable\nSchoolsBuddy.PublicAPI.Models.ErrorResponse.Error. See cross-cutting-design.md §5.3. This is additive —\nexisting endpoints continue returning their legacy plain-string /\nModelState shapes until migrated by their per-controller ticket."}}},"paths":{"/api/v1/Staff/{id}":{"put":{"tags":["Staff"],"summary":"Partially updates a staff member — omitted (or explicitly null) fields\npreserve their stored values (BP10 / §3.7e, D14). Sending\n`isArchived` archives or unarchives; omitting it leaves the\narchive state alone. An archived staff member accepts only a PUT carrying\n`isArchived: false`. The response is the staff member as stored after\nthe write — including when the PUT has just archived it.","parameters":[{"name":"id","in":"path","description":"The staff member id (Person.Id)","required":true,"schema":{"type":"integer","format":"int32"}},{"name":"organisationId","in":"query","description":"The organisation the staff member belongs to — required when the client has access to multiple organisations","schema":{"type":"integer","format":"int32"}}],"requestBody":{"description":"The update request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StaffUpdateRequestDto"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StaffCoreDto"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## PATCH /api/v1/Staff/BulkUpdateOnlineMeetingId

> Bulk update OnlineMeetingId for staff members.\
> \
> \<b>Breaking (SB-15677, hard cut):\</b> the request body was a bare JSON\
> array of items and is now the \`{ "items": \[ ... ] }\` envelope; the\
> old shape returns \`400 VALIDATION\_FAILED\`. The response was an\
> empty \`200\` and is now the standard bulk envelope.\
> Items are processed independently (BP4), like every other bulk endpoint: an\
> invalid item fails with \`VALIDATION\_FAILED\`, an id that is not an active\
> staff member of the organisation with \`STAFF\_NOT\_FOUND\`, a SchoolsBuddy\
> support user with \`CONFLICT\` — each in \`failedItems\` at its own index —\
> while every valid item is written and the whole call returns \`200\`. A staff\
> member with no meeting id yet can be given one. When an id appears more than\
> once, the last occurrence is the value stored.

```json
{"openapi":"3.0.4","info":{"title":"SchoolsBuddy Public API","version":"1.0"},"tags":[{"name":"Staff"}],"servers":[{"url":"https://publicapi-eu.schoolsbuddy.net","description":"EMEA Public Api server"},{"url":"https://publicapi-asia.schoolsbuddy.net","description":"Asia Public Api server"},{"url":"https://publicapi-us.schoolsbuddy.net","description":"US Public Api server"},{"url":"https://publicapi.schoolsbuddy.cn","description":"China Public Api server"},{"url":"https://identity-eu.schoolsbuddy.net","description":"EMEA Identity server"},{"url":"https://identity-asia.schoolsbuddy.net","description":"Asia Identity server"},{"url":"https://identity-us.schoolsbuddy.net","description":"US Identity server"},{"url":"https://accounts.schoolsbuddy.cn","description":"China Identity server"}],"security":[{"Bearer":[]}],"components":{"securitySchemes":{"Bearer":{"type":"apiKey","description":"Type \"Bearer\" followed by a space and a token.","name":"Authorization","in":"header"}},"schemas":{"StaffBulkUpdateOnlineMeetingIdRequestDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/StaffOnlineMeetingIdItemDto"},"nullable":true}},"additionalProperties":false},"StaffOnlineMeetingIdItemDto":{"required":["id","onlineMeetingId"],"type":"object","properties":{"id":{"type":"integer","format":"int32"},"onlineMeetingId":{"maxLength":250,"minLength":1,"type":"string"}},"additionalProperties":false},"Int32BulkOperationResult":{"type":"object","properties":{"successfulIds":{"type":"array","items":{"type":"integer","format":"int32"},"description":"Gets or sets the ids of the items that were processed successfully.\nOn BulkCreate these are the newly-created ids.","nullable":true},"failedItems":{"type":"array","items":{"$ref":"#/components/schemas/BulkFailedItem"},"description":"Gets or sets the per-item failures, each carrying its request index,\noptional client reference, name, machine-readable code, and message.","nullable":true},"totalRequested":{"type":"integer","description":"Gets or sets the total number of items in the request. Set by the\ncaller (it is not derivable from the success/failure lists alone —\nitems rejected before per-item processing may appear in neither).","format":"int32"},"totalSuccessful":{"type":"integer","description":"Gets the number of items processed successfully (computed).","format":"int32","readOnly":true},"totalFailed":{"type":"integer","description":"Gets the number of items that failed (computed).","format":"int32","readOnly":true}},"additionalProperties":false,"description":"Standard envelope returned by every Public API bulk endpoint\n(BulkCreate / BulkUpdate / BulkArchive). Each item in the request is\nprocessed independently — one item failing does not roll back the\nothers — and the envelope reports per-item outcome. See\ncross-cutting-design.md §4."},"BulkFailedItem":{"type":"object","properties":{"index":{"type":"integer","description":"Gets or sets the zero-based index of the failed item within the\nrequest array, so callers keeping request order can map it back.","format":"int32"},"clientReferenceId":{"type":"string","description":"Gets or sets the optional opaque client-supplied reference echoed\nback from the request item. Null when the caller did not supply one.","nullable":true},"name":{"type":"string","description":"Gets or sets the name of the entity the failed item referred to,\nfor at-a-glance identification in the response.","nullable":true},"code":{"type":"string","description":"Gets or sets the machine-readable error code (e.g.\n`VALIDATION_FAILED`, `GROUP_IMPORTED_READ_ONLY`) per\ncross-cutting-design.md §5.1.","nullable":true},"error":{"type":"string","description":"Gets or sets the human-readable error message.","nullable":true}},"additionalProperties":false,"description":"A single per-item failure entry in a SchoolsBuddy.PublicAPI.Models.BulkOperationResult`1\nenvelope. Mirrors the structured error body (cross-cutting-design.md §5.3):\na machine-readable SchoolsBuddy.PublicAPI.Models.BulkFailedItem.Code plus a human-readable SchoolsBuddy.PublicAPI.Models.BulkFailedItem.Error."},"ErrorResponse":{"type":"object","properties":{"code":{"type":"string","description":"Gets or sets the machine-readable error code (e.g.\n`VALIDATION_FAILED`, `RESOURCE_NOT_FOUND`,\n`INTERNAL_ERROR`) per cross-cutting-design.md §5.1.","nullable":true},"error":{"type":"string","description":"Gets or sets the human-readable error message.","nullable":true}},"additionalProperties":false,"description":"Structured body for 4xx / 5xx responses on the new Public API surface:\na machine-readable SchoolsBuddy.PublicAPI.Models.ErrorResponse.Code plus a human-readable\nSchoolsBuddy.PublicAPI.Models.ErrorResponse.Error. See cross-cutting-design.md §5.3. This is additive —\nexisting endpoints continue returning their legacy plain-string /\nModelState shapes until migrated by their per-controller ticket."}}},"paths":{"/api/v1/Staff/BulkUpdateOnlineMeetingId":{"patch":{"tags":["Staff"],"summary":"Bulk update OnlineMeetingId for staff members.\n\n<b>Breaking (SB-15677, hard cut):</b> the request body was a bare JSON\narray of items and is now the `{ \"items\": [ ... ] }` envelope; the\nold shape returns `400 VALIDATION_FAILED`. The response was an\nempty `200` and is now the standard bulk envelope.\nItems are processed independently (BP4), like every other bulk endpoint: an\ninvalid item fails with `VALIDATION_FAILED`, an id that is not an active\nstaff member of the organisation with `STAFF_NOT_FOUND`, a SchoolsBuddy\nsupport user with `CONFLICT` — each in `failedItems` at its own index —\nwhile every valid item is written and the whole call returns `200`. A staff\nmember with no meeting id yet can be given one. When an id appears more than\nonce, the last occurrence is the value stored.","parameters":[{"name":"organisationId","in":"query","description":"The organisation the staff members belong to — required when the client has access to multiple organisations","schema":{"type":"integer","format":"int32"}}],"requestBody":{"description":"The bulk update envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StaffBulkUpdateOnlineMeetingIdRequestDto"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Int32BulkOperationResult"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## POST /api/v1/Staff/BulkArchive

> Bulk archive or unarchive staff.\
> \
> \<b>Breaking (SB-15677):\</b> the response was an empty \`200\` and is\
> now the standard bulk envelope. The request body and the\
> \`organisationId\` query parameter are unchanged. Items are\
> processed independently (BP4) — an id that is not a staff member of\
> the organisation fails only its own item with\
> \`STAFF\_NOT\_FOUND\`, and the whole call still returns \`200\`.\
> SchoolsBuddy support users were silently skipped before and now fail\
> their item with \`CONFLICT\`.

```json
{"openapi":"3.0.4","info":{"title":"SchoolsBuddy Public API","version":"1.0"},"tags":[{"name":"Staff"}],"servers":[{"url":"https://publicapi-eu.schoolsbuddy.net","description":"EMEA Public Api server"},{"url":"https://publicapi-asia.schoolsbuddy.net","description":"Asia Public Api server"},{"url":"https://publicapi-us.schoolsbuddy.net","description":"US Public Api server"},{"url":"https://publicapi.schoolsbuddy.cn","description":"China Public Api server"},{"url":"https://identity-eu.schoolsbuddy.net","description":"EMEA Identity server"},{"url":"https://identity-asia.schoolsbuddy.net","description":"Asia Identity server"},{"url":"https://identity-us.schoolsbuddy.net","description":"US Identity server"},{"url":"https://accounts.schoolsbuddy.cn","description":"China Identity server"}],"security":[{"Bearer":[]}],"components":{"securitySchemes":{"Bearer":{"type":"apiKey","description":"Type \"Bearer\" followed by a space and a token.","name":"Authorization","in":"header"}},"schemas":{"StaffBulkArchiveRequestDto":{"required":["ids"],"type":"object","properties":{"archive":{"type":"boolean"},"ids":{"minItems":1,"type":"array","items":{"type":"integer","format":"int32"}}},"additionalProperties":false},"Int32BulkOperationResult":{"type":"object","properties":{"successfulIds":{"type":"array","items":{"type":"integer","format":"int32"},"description":"Gets or sets the ids of the items that were processed successfully.\nOn BulkCreate these are the newly-created ids.","nullable":true},"failedItems":{"type":"array","items":{"$ref":"#/components/schemas/BulkFailedItem"},"description":"Gets or sets the per-item failures, each carrying its request index,\noptional client reference, name, machine-readable code, and message.","nullable":true},"totalRequested":{"type":"integer","description":"Gets or sets the total number of items in the request. Set by the\ncaller (it is not derivable from the success/failure lists alone —\nitems rejected before per-item processing may appear in neither).","format":"int32"},"totalSuccessful":{"type":"integer","description":"Gets the number of items processed successfully (computed).","format":"int32","readOnly":true},"totalFailed":{"type":"integer","description":"Gets the number of items that failed (computed).","format":"int32","readOnly":true}},"additionalProperties":false,"description":"Standard envelope returned by every Public API bulk endpoint\n(BulkCreate / BulkUpdate / BulkArchive). Each item in the request is\nprocessed independently — one item failing does not roll back the\nothers — and the envelope reports per-item outcome. See\ncross-cutting-design.md §4."},"BulkFailedItem":{"type":"object","properties":{"index":{"type":"integer","description":"Gets or sets the zero-based index of the failed item within the\nrequest array, so callers keeping request order can map it back.","format":"int32"},"clientReferenceId":{"type":"string","description":"Gets or sets the optional opaque client-supplied reference echoed\nback from the request item. Null when the caller did not supply one.","nullable":true},"name":{"type":"string","description":"Gets or sets the name of the entity the failed item referred to,\nfor at-a-glance identification in the response.","nullable":true},"code":{"type":"string","description":"Gets or sets the machine-readable error code (e.g.\n`VALIDATION_FAILED`, `GROUP_IMPORTED_READ_ONLY`) per\ncross-cutting-design.md §5.1.","nullable":true},"error":{"type":"string","description":"Gets or sets the human-readable error message.","nullable":true}},"additionalProperties":false,"description":"A single per-item failure entry in a SchoolsBuddy.PublicAPI.Models.BulkOperationResult`1\nenvelope. Mirrors the structured error body (cross-cutting-design.md §5.3):\na machine-readable SchoolsBuddy.PublicAPI.Models.BulkFailedItem.Code plus a human-readable SchoolsBuddy.PublicAPI.Models.BulkFailedItem.Error."},"ErrorResponse":{"type":"object","properties":{"code":{"type":"string","description":"Gets or sets the machine-readable error code (e.g.\n`VALIDATION_FAILED`, `RESOURCE_NOT_FOUND`,\n`INTERNAL_ERROR`) per cross-cutting-design.md §5.1.","nullable":true},"error":{"type":"string","description":"Gets or sets the human-readable error message.","nullable":true}},"additionalProperties":false,"description":"Structured body for 4xx / 5xx responses on the new Public API surface:\na machine-readable SchoolsBuddy.PublicAPI.Models.ErrorResponse.Code plus a human-readable\nSchoolsBuddy.PublicAPI.Models.ErrorResponse.Error. See cross-cutting-design.md §5.3. This is additive —\nexisting endpoints continue returning their legacy plain-string /\nModelState shapes until migrated by their per-controller ticket."}}},"paths":{"/api/v1/Staff/BulkArchive":{"post":{"tags":["Staff"],"summary":"Bulk archive or unarchive staff.\n\n<b>Breaking (SB-15677):</b> the response was an empty `200` and is\nnow the standard bulk envelope. The request body and the\n`organisationId` query parameter are unchanged. Items are\nprocessed independently (BP4) — an id that is not a staff member of\nthe organisation fails only its own item with\n`STAFF_NOT_FOUND`, and the whole call still returns `200`.\nSchoolsBuddy support users were silently skipped before and now fail\ntheir item with `CONFLICT`.","parameters":[{"name":"organisationId","in":"query","description":"The organisation the staff members belong to — required when the client has access to multiple organisations","schema":{"type":"integer","format":"int32"}}],"requestBody":{"description":"The bulk archive request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StaffBulkArchiveRequestDto"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Int32BulkOperationResult"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```
