> ## Documentation Index
> Fetch the complete documentation index at: https://developers.jobhandy.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Mitarbeiter aktualisieren

> Aktualisiert Mitarbeiterdaten. `divisionId` ändert oder entfernt die Division des Mitarbeiters innerhalb desselben Tenants. Dieser Endpoint kann einen bereits zugeordneten Mitarbeiter nicht in einen anderen Tenant verschieben. Mit `dryRun=true` gibt die API den projizierten Mitarbeiter zurück, ohne ihn zu speichern.

## Auf einen Blick

| Eigenschaft       | Verhalten                                                                            |
| ----------------- | ------------------------------------------------------------------------------------ |
| Authentifizierung | Erforderlich in `X-API-Key`                                                          |
| Tenant-Kontext    | Optionale Einschränkung; Ressource und Referenzen müssen im Scope bleiben            |
| Dry Run           | Unterstützt mit `dryRun=true`                                                        |
| Request-Body      | `application/json`; geschlossenes Schema; maximal dokumentierte Body-Größe 5 MiB     |
| Response          | JSON                                                                                 |
| Primärer Erfolg   | `200`                                                                                |
| Side Effects      | Speichert unterstützte Mitarbeiteränderungen; Dry Run unterdrückt die Speicherung    |
| Retry-Empfehlung  | Mitarbeiter erneut lesen und gewünschte Felder vergleichen, bevor ein Replay erfolgt |

## Betriebsverhalten

Aktualisiert Mitarbeiterdaten. `divisionId` ändert oder entfernt die Division des Mitarbeiters innerhalb desselben Tenants. Dieser Endpoint kann einen bereits zugeordneten Mitarbeiter nicht in einen anderen Tenant verschieben. Mit `dryRun=true` gibt die API den projizierten Mitarbeiter zurück, ohne ihn zu speichern.

* Ausgelassene Eigenschaften bleiben unverändert; nullable Eigenschaften können mit `null` geleert werden.
* `divisionId` kann die Zuordnung nur innerhalb desselben Tenants ändern oder entfernen.
* Mindestens eine Patch-Eigenschaft ist erforderlich.

## Häufige Fehler

| Fehlercode               | Bedeutung                                                   |
| ------------------------ | ----------------------------------------------------------- |
| `VALIDATION_ERROR`       | Schema- oder fachliche Validierung ist fehlgeschlagen       |
| `INVALID_REQUEST_ID`     | `X-Request-ID` ist keine UUID v4 oder v7                    |
| `INVALID_API_KEY`        | API-Key fehlt, ist ungültig, gelöscht oder inaktiv          |
| `TENANT_NOT_IN_SCOPE`    | Ausgewählter Tenant liegt außerhalb des API-Key-Scopes      |
| `NOT_FOUND`              | Ressource fehlt oder ist im Scope nicht zugänglich          |
| `NOT_ACCEPTABLE`         | Angeforderter Response-Medientyp ist nicht verfügbar        |
| `DUPLICATE_RESOURCE`     | Eine Eindeutigkeitsregel wird bereits erfüllt               |
| `PAYLOAD_TOO_LARGE`      | Vollständiger Request überschreitet das dokumentierte Limit |
| `UNSUPPORTED_MEDIA_TYPE` | Request-Medientyp wird nicht akzeptiert                     |
| `INVALID_REFERENCE`      | Referenzierte Ressource fehlt oder ist nicht verfügbar      |
| `RATE_LIMIT_EXCEEDED`    | Rate Limit des API-Keys wurde überschritten                 |
| `INTERNAL_SERVER_ERROR`  | Unerwarteter Serverfehler                                   |

Die Response-Liste der Operation und die Seite [Fehlerbehandlung](/de/concepts/error-handling) sind für die vollständige Behandlung maßgeblich.

## Vor der Implementierung

* Erzeugen und protokollieren Sie für den Versuch eine neue `X-Request-ID`.
* Behandeln Sie jeden dokumentierten Response-Status.
* Protokollieren Sie weder `X-API-Key` noch unnötige personenbezogene Daten.
* Gleichen Sie den aktuellen Ressourcenstatus ab, bevor Sie einen mehrdeutigen Write wiederholen.

<Card title="Zugehöriger Integrationsleitfaden" href="/de/guides/sync-employees" horizontal>
  Prüfen Sie den vollständigen Prozess sowie Status-, Retry- und Betriebsmuster für diese Operation.
</Card>


## OpenAPI

````yaml https://assets.jobhandy.io/api-spec/jobhandy-public-api.openapi.json PATCH /employees/{id}
openapi: 3.1.0
info:
  title: JobHandy Public API
  version: 1.0.0
  summary: Production API for HR, order, incident, division, and payroll integrations.
  description: >-
    Integrate HR and payroll systems with JobHandy through a versioned REST API.


    ## Production endpoint


    All public requests use `https://api.jobhandy.io/v1`.


    ## Core conventions


    - Authenticate protected operations with `X-API-Key`.

    - Use `X-Tenant-ID` where supported to select one tenant within the API-key
    scope.

    - Use `X-Request-ID` for end-to-end request correlation.

    - Validate supported writes with `dryRun=true` before applying them.

    - Collection endpoints support pagination, sorting, and the documented
    filter expression language.

    - Error responses use a stable JSON envelope with a machine-readable error
    code.


    Optional query and header parameters are documented but omitted from
    generated requests by default in the accompanying Mintlify configuration.
servers:
  - url: https://api.jobhandy.io/v1
    description: Production
security:
  - apiKeyAuth: []
tags:
  - name: Employees
    description: Synchronize employee master data, account state, and division assignments.
  - name: Orders
    description: Read employee orders, record HR decisions, and download order documents.
  - name: Incidents
    description: Report and maintain employee incidents and upload supported attachments.
  - name: Divisions
    description: Maintain organizational divisions, hierarchy, ordering, and cost centers.
  - name: Payroll export documents
    description: List payroll export metadata and download generated payroll files.
  - name: Health
    description: Check basic public API availability without authentication.
paths:
  /employees/{id}:
    patch:
      tags:
        - Employees
      summary: Update an employee
      description: >-
        Updates employee data. `divisionId` changes or removes the employee's
        division within the same tenant. This endpoint cannot move an assigned
        employee to another tenant. With `dryRun=true`, the API returns the
        projected employee without saving it.
      operationId: updateEmployee
      parameters:
        - in: path
          name: id
          description: Employee ID.
          required: true
          schema:
            type: string
            pattern: ^[0-9a-fA-F]{24}$
            example: 68920e08eeaea4f2301eecb3
        - in: query
          required: false
          name: dryRun
          description: >-
            When `true`, the API validates the request without applying the
            change. The operation's responses specify the returned
            representation. When omitted, the server uses `false`.
          schema:
            type: boolean
            example: true
            x-mint:
              post:
                - optional
                - 'server default: false'
                - not sent by default
            x-client-default-state: inactive
        - name: X-Tenant-ID
          description: >-
            Narrows the operation to one tenant in the API key's scope. Any
            referenced or target resource must be accessible through that
            tenant. In interactive clients, use the `{{tenantId}}` variable when
            a tenant must be selected. Keep the header disabled when tenant
            selection is not required.
          in: header
          required: false
          schema:
            type: string
            pattern: ^[0-9a-fA-F]{24}$
            x-mint:
              post:
                - optional
                - not sent by default
            x-client-default-state: inactive
            x-default: '{{tenantId}}'
        - in: header
          name: X-Request-ID
          required: false
          description: >-
            Optional request identifier. If supplied, it must be a UUID v4 or v7
            and is returned unchanged in every response. If omitted, the API
            generates one. Invalid values return `400 INVALID_REQUEST_ID`. If
            your client uses a `{{requestId}}` variable, refresh it with a new
            UUID version 4 or 7 for every HTTP request attempt. Keep the header
            disabled to let the API generate the request identifier.
          schema:
            type: string
            format: uuid
            pattern: >-
              ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[47][0-9a-fA-F]{3}-[89aAbB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$
            x-mint:
              post:
                - optional
                - not sent by default
            x-client-default-state: inactive
            x-default: '{{requestId}}'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EmployeePatch'
            examples:
              updateProfile:
                summary: Update profile fields
                value:
                  firstName: Alexandra
                  phoneNumber: +49 221 5550199
                  city: Cologne
              clearOptionalFields:
                summary: Clear nullable optional fields
                value:
                  privateEmail: null
                  phoneNumber: null
                  additionalInfo: null
              blockAccount:
                summary: Block the employee account
                value:
                  blocked: true
              assignDivision:
                summary: Assign another division in the same tenant
                value:
                  divisionId: 68920e08eeaea4f2301eecb4
              removeDivision:
                summary: Remove the division assignment
                value:
                  divisionId: null
        description: The JSON request body must not exceed 5,242,880 bytes.
        x-max-request-body-bytes: 5242880
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Employee'
              examples:
                updated:
                  summary: Updated employee
                  value:
                    id: 68a000000000000000000001
                    email: alex.morgan@example.com
                    privateEmail: alex.morgan.private@example.net
                    employeeNumber: EMP-1042
                    firstName: Alex
                    lastName: Morgan
                    phoneNumber: +49 221 5550100
                    street: Example Street 12
                    postalCode: '50667'
                    city: Cologne
                    countryCode: DE
                    additionalInfo: Building B, third floor
                    blocked: false
                    tenant: 68a000000000000000000010
                    divisionId: 68920e08eeaea4f2301eecb3
                    createdAt: '2026-06-01T08:00:00.000Z'
                    updatedAt: '2026-07-15T11:30:00.000Z'
                dryRunPreview:
                  summary: Projected dry-run result
                  value:
                    id: 68a000000000000000000001
                    email: alex.morgan@example.com
                    privateEmail: alex.morgan.private@example.net
                    employeeNumber: EMP-1042
                    firstName: Alex
                    lastName: Morgan
                    phoneNumber: +49 221 5550100
                    street: Example Street 12
                    postalCode: '50667'
                    city: Cologne
                    countryCode: DE
                    additionalInfo: Building B, third floor
                    blocked: false
                    tenant: 68a000000000000000000010
                    divisionId: 68920e08eeaea4f2301eecb3
                    createdAt: '2026-06-01T08:00:00.000Z'
                    updatedAt: '2026-07-15T11:30:00.000Z'
          description: >-
            Returns the updated employee, or the projected employee when
            `dryRun=true`.
          headers:
            X-Request-ID:
              description: Request identifier returned for every public API response.
              schema:
                type: string
                format: uuid
                pattern: >-
                  ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[47][0-9a-fA-F]{3}-[89aAbB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$
                example: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
            RateLimit-Policy:
              description: Request quota policy expressed as an HTTP structured field.
              schema:
                type: string
            RateLimit:
              description: Current request quota availability and effective window.
              schema:
                type: string
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                validationError:
                  summary: >-
                    The request cannot be parsed or violates the request
                    contract.
                  value:
                    error:
                      code: VALIDATION_ERROR
                      message: The request contains an invalid value.
                      requestId: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
                invalidRequestId:
                  summary: X-Request-ID is not UUID v4 or v7
                  value:
                    error:
                      code: INVALID_REQUEST_ID
                      message: The supplied X-Request-ID is invalid.
                      requestId: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
          description: The request cannot be parsed or violates the request contract.
          headers:
            X-Request-ID:
              description: Request identifier returned for every public API response.
              schema:
                type: string
                format: uuid
                pattern: >-
                  ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[47][0-9a-fA-F]{3}-[89aAbB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$
                example: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                invalidApiKey:
                  summary: API key is missing, invalid, or inactive
                  value:
                    error:
                      code: INVALID_API_KEY
                      message: The supplied API key is missing, invalid, or inactive.
                      requestId: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
          description: The X-API-Key credential is missing, invalid, or inactive.
          headers:
            X-Request-ID:
              description: Request identifier returned for every public API response.
              schema:
                type: string
                format: uuid
                pattern: >-
                  ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[47][0-9a-fA-F]{3}-[89aAbB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$
                example: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                tenantNotInScope:
                  summary: Selected tenant is not in the API-key scope
                  value:
                    error:
                      code: TENANT_NOT_IN_SCOPE
                      message: >-
                        The integration does not have access to the selected
                        tenant.
                      requestId: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
          description: The API key does not grant access to the selected tenant.
          headers:
            X-Request-ID:
              description: Request identifier returned for every public API response.
              schema:
                type: string
                format: uuid
                pattern: >-
                  ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[47][0-9a-fA-F]{3}-[89aAbB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$
                example: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
            RateLimit-Policy:
              description: Request quota policy expressed as an HTTP structured field.
              schema:
                type: string
            RateLimit:
              description: Current request quota availability and effective window.
              schema:
                type: string
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                notFound:
                  summary: >-
                    The resource was not found or is outside the API key's
                    scope.
                  value:
                    error:
                      code: NOT_FOUND
                      message: The requested resource was not found.
                      requestId: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
          description: The resource was not found or is outside the API key's scope.
          headers:
            X-Request-ID:
              description: Request identifier returned for every public API response.
              schema:
                type: string
                format: uuid
                pattern: >-
                  ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[47][0-9a-fA-F]{3}-[89aAbB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$
                example: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
            RateLimit-Policy:
              description: Request quota policy expressed as an HTTP structured field.
              schema:
                type: string
            RateLimit:
              description: Current request quota availability and effective window.
              schema:
                type: string
        '406':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                notAcceptable:
                  summary: Accept excludes all success media types
                  value:
                    error:
                      code: NOT_ACCEPTABLE
                      message: >-
                        The endpoint cannot produce a response in a media type
                        accepted by the request.
                      requestId: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
          description: The requested response media type is not supported.
          headers:
            X-Request-ID:
              description: Request identifier returned for every public API response.
              schema:
                type: string
                format: uuid
                pattern: >-
                  ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[47][0-9a-fA-F]{3}-[89aAbB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$
                example: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                duplicateResource:
                  summary: A resource with the same unique value already exists.
                  value:
                    error:
                      code: DUPLICATE_RESOURCE
                      message: A resource with the same unique value already exists.
                      requestId: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
          description: >-
            The requested change conflicts with the resource's current state or
            with an existing resource.
          headers:
            X-Request-ID:
              description: Request identifier returned for every public API response.
              schema:
                type: string
                format: uuid
                pattern: >-
                  ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[47][0-9a-fA-F]{3}-[89aAbB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$
                example: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
            RateLimit-Policy:
              description: Request quota policy expressed as an HTTP structured field.
              schema:
                type: string
            RateLimit:
              description: Current request quota availability and effective window.
              schema:
                type: string
        '413':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                payloadTooLarge:
                  summary: Request body exceeds 5 MiB
                  value:
                    error:
                      code: PAYLOAD_TOO_LARGE
                      message: The request body exceeds the maximum allowed size.
                      requestId: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
          description: The request body exceeds 5 MiB.
          headers:
            X-Request-ID:
              description: Request identifier returned for every public API response.
              schema:
                type: string
                format: uuid
                pattern: >-
                  ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[47][0-9a-fA-F]{3}-[89aAbB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$
                example: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
        '415':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                unsupportedMediaType:
                  summary: Content-Type is not supported
                  value:
                    error:
                      code: UNSUPPORTED_MEDIA_TYPE
                      message: >-
                        The request body media type is not supported by this
                        endpoint.
                      requestId: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
          description: The request body media type is not supported by the endpoint.
          headers:
            X-Request-ID:
              description: Request identifier returned for every public API response.
              schema:
                type: string
                format: uuid
                pattern: >-
                  ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[47][0-9a-fA-F]{3}-[89aAbB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$
                example: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                validationError:
                  summary: >-
                    The request matches the contract, but a value or referenced
                    resource fails validation.
                  value:
                    error:
                      code: VALIDATION_ERROR
                      message: The request contains an invalid value.
                      requestId: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
                invalidReference:
                  summary: Division cannot be used
                  value:
                    error:
                      code: INVALID_REFERENCE
                      message: The referenced division is invalid for this request.
                      requestId: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
          description: >-
            The request matches the contract, but a value or referenced resource
            fails validation.
          headers:
            X-Request-ID:
              description: Request identifier returned for every public API response.
              schema:
                type: string
                format: uuid
                pattern: >-
                  ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[47][0-9a-fA-F]{3}-[89aAbB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$
                example: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
            RateLimit-Policy:
              description: Request quota policy expressed as an HTTP structured field.
              schema:
                type: string
            RateLimit:
              description: Current request quota availability and effective window.
              schema:
                type: string
        '429':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                rateLimitExceeded:
                  summary: API-key request quota exceeded
                  value:
                    error:
                      code: RATE_LIMIT_EXCEEDED
                      message: The API key request rate limit has been exceeded.
                      requestId: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
          description: The API key request rate limit was exceeded.
          headers:
            X-Request-ID:
              description: Request identifier returned for every public API response.
              schema:
                type: string
                format: uuid
                pattern: >-
                  ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[47][0-9a-fA-F]{3}-[89aAbB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$
                example: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
            RateLimit-Policy:
              description: Request quota policy expressed as an HTTP structured field.
              schema:
                type: string
            RateLimit:
              description: Current request quota availability and effective window.
              schema:
                type: string
            Retry-After:
              description: >-
                Seconds to wait before retrying after request-rate admission was
                rejected.
              schema:
                type: integer
                example: 60
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                internalServerError:
                  summary: Unexpected server error
                  value:
                    error:
                      code: INTERNAL_SERVER_ERROR
                      message: The request failed.
                      requestId: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
          description: An unexpected server error occurred.
          headers:
            X-Request-ID:
              description: Request identifier returned for every public API response.
              schema:
                type: string
                format: uuid
                pattern: >-
                  ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[47][0-9a-fA-F]{3}-[89aAbB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$
                example: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
      security:
        - apiKeyAuth: []
components:
  schemas:
    EmployeePatch:
      type: object
      properties:
        firstName:
          type: string
          pattern: \S
          maxLength: 1000
          minLength: 1
          description: >-
            Replacement first name. Omit the field to leave it unchanged; `null`
            is not accepted.
          example: Alexandra
          x-mint:
            post:
              - optional
              - not sent by default
          x-client-default-state: inactive
        lastName:
          type: string
          pattern: \S
          maxLength: 1000
          minLength: 1
          description: >-
            Replacement last name. Omit the field to leave it unchanged; `null`
            is not accepted.
          example: Morgan
          x-mint:
            post:
              - optional
              - not sent by default
          x-client-default-state: inactive
        privateEmail:
          type:
            - string
            - 'null'
          format: email
          description: >-
            Replacement private email address. Use `null` to clear the stored
            value.
          example: alex.private@example.net
          x-mint:
            post:
              - nullable
              - optional
              - not sent by default
          x-client-default-state: inactive
        employeeNumber:
          type:
            - string
            - 'null'
          description: Replacement employee number. Use `null` to clear the stored value.
          example: EMP-2042
          x-mint:
            post:
              - nullable
              - optional
              - not sent by default
          x-client-default-state: inactive
        phoneNumber:
          type:
            - string
            - 'null'
          description: Replacement phone number. Use `null` to clear the stored value.
          example: +49 221 5550199
          x-mint:
            post:
              - nullable
              - optional
              - not sent by default
          x-client-default-state: inactive
        street:
          type:
            - string
            - 'null'
          maxLength: 1000
          pattern: \S
          description: >-
            Replacement street and house number. Use `null` to clear the stored
            value.
          example: New Street 7
          x-mint:
            post:
              - nullable
              - optional
              - not sent by default
          x-client-default-state: inactive
        postalCode:
          type:
            - string
            - 'null'
          maxLength: 1000
          pattern: \S
          description: Replacement postal code. Use `null` to clear the stored value.
          example: '50668'
          x-mint:
            post:
              - nullable
              - optional
              - not sent by default
          x-client-default-state: inactive
        city:
          type:
            - string
            - 'null'
          maxLength: 1000
          pattern: \S
          description: Replacement city. Use `null` to clear the stored value.
          example: Cologne
          x-mint:
            post:
              - nullable
              - optional
              - not sent by default
          x-client-default-state: inactive
        countryCode:
          type: string
          description: Replacement uppercase two-character country or territory code.
          enum:
            - AC
            - AD
            - AE
            - AF
            - AG
            - AI
            - AL
            - AM
            - AO
            - AQ
            - AR
            - AS
            - AT
            - AU
            - AW
            - AX
            - AZ
            - BA
            - BB
            - BD
            - BE
            - BF
            - BG
            - BH
            - BI
            - BJ
            - BL
            - BM
            - BN
            - BO
            - BQ
            - BR
            - BS
            - BT
            - BV
            - BW
            - BY
            - BZ
            - CA
            - CC
            - CD
            - CF
            - CG
            - CH
            - CI
            - CK
            - CL
            - CM
            - CN
            - CO
            - CR
            - CU
            - CV
            - CW
            - CX
            - CY
            - CZ
            - DE
            - DJ
            - DK
            - DM
            - DO
            - DZ
            - EC
            - EE
            - EG
            - EH
            - ER
            - ES
            - ET
            - FI
            - FJ
            - FK
            - FM
            - FO
            - FR
            - GA
            - GB
            - GD
            - GE
            - GF
            - GG
            - GH
            - GI
            - GL
            - GM
            - GN
            - GP
            - GQ
            - GR
            - GS
            - GT
            - GU
            - GW
            - GY
            - HK
            - HM
            - HN
            - HR
            - HT
            - HU
            - ID
            - IE
            - IL
            - IM
            - IN
            - IO
            - IQ
            - IR
            - IS
            - IT
            - JE
            - JM
            - JO
            - JP
            - KE
            - KG
            - KH
            - KI
            - KM
            - KN
            - KP
            - KR
            - KW
            - KY
            - KZ
            - LA
            - LB
            - LC
            - LI
            - LK
            - LR
            - LS
            - LT
            - LU
            - LV
            - LY
            - MA
            - MC
            - MD
            - ME
            - MF
            - MG
            - MH
            - MK
            - ML
            - MM
            - MN
            - MO
            - MP
            - MQ
            - MR
            - MS
            - MT
            - MU
            - MV
            - MW
            - MX
            - MY
            - MZ
            - NA
            - NC
            - NE
            - NF
            - NG
            - NI
            - NL
            - 'NO'
            - NP
            - NR
            - NU
            - NZ
            - OM
            - PA
            - PE
            - PF
            - PG
            - PH
            - PK
            - PL
            - PM
            - PN
            - PR
            - PS
            - PT
            - PW
            - PY
            - QA
            - RE
            - RO
            - RS
            - RU
            - RW
            - SA
            - SB
            - SC
            - SD
            - SE
            - SG
            - SH
            - SI
            - SJ
            - SK
            - SL
            - SM
            - SN
            - SO
            - SR
            - SS
            - ST
            - SV
            - SX
            - SY
            - SZ
            - TA
            - TC
            - TD
            - TF
            - TG
            - TH
            - TJ
            - TK
            - TL
            - TM
            - TN
            - TO
            - TR
            - TT
            - TV
            - TW
            - TZ
            - UA
            - UG
            - UM
            - US
            - UY
            - UZ
            - VA
            - VC
            - VE
            - VG
            - VI
            - VN
            - VU
            - WF
            - WS
            - XK
            - YE
            - YT
            - ZA
            - ZM
            - ZW
          example: DE
          x-mint:
            post:
              - optional
              - not sent by default
          x-client-default-state: inactive
        additionalInfo:
          type:
            - string
            - 'null'
          maxLength: 1000
          description: >-
            Replacement additional information. Use `null` to clear the stored
            value.
          example: null
          x-mint:
            post:
              - nullable
              - optional
              - not sent by default
          x-client-default-state: inactive
        blocked:
          type: boolean
          description: >-
            Set to `true` to block the employee account or `false` to unblock
            it.
          example: false
          x-mint:
            post:
              - optional
              - not sent by default
          x-client-default-state: inactive
        divisionId:
          description: >-
            New division ID within the current tenant. Use `null` to remove only
            the division assignment; this does not move the employee to another
            tenant.
          type:
            - string
            - 'null'
          pattern: ^[0-9a-fA-F]{24}$
          example: 68920e08eeaea4f2301eecb4
          x-mint:
            post:
              - nullable
              - optional
              - not sent by default
          x-client-default-state: inactive
      description: Editable employee fields. At least one field is required.
      minProperties: 1
      additionalProperties: false
      example:
        phoneNumber: +49 221 5550199
        additionalInfo: null
        blocked: false
        divisionId: 68920e08eeaea4f2301eecb4
    Employee:
      type: object
      properties:
        id:
          type: string
          description: Unique employee identifier.
          pattern: ^[0-9a-fA-F]{24}$
          readOnly: true
          example: 68a000000000000000000001
        email:
          type: string
          description: >-
            Work email address used by the employee account. This field is not
            editable through the update endpoint.
          format: email
          example: alex.morgan@example.com
        privateEmail:
          description: Optional private email address, or `null` when none is stored.
          type:
            - string
            - 'null'
          example: alex.morgan.private@example.net
          x-mint:
            post:
              - nullable
              - optional
        employeeNumber:
          description: >-
            Customer-defined personnel or employee number, or `null` when none
            is assigned.
          type:
            - string
            - 'null'
          example: EMP-1042
          x-mint:
            post:
              - nullable
              - optional
        firstName:
          description: >-
            Employee first name, or `null` when unavailable in an existing
            record.
          type:
            - string
            - 'null'
          example: Alex
          x-mint:
            post:
              - nullable
              - optional
        lastName:
          description: >-
            Employee last name, or `null` when unavailable in an existing
            record.
          type:
            - string
            - 'null'
          example: Morgan
          x-mint:
            post:
              - nullable
              - optional
        phoneNumber:
          description: Employee phone number, or `null` when none is stored.
          type:
            - string
            - 'null'
          example: +49 221 5550100
          x-mint:
            post:
              - nullable
              - optional
        street:
          description: Street and house number, or `null` when no address is stored.
          type:
            - string
            - 'null'
          example: Example Street 12
          x-mint:
            post:
              - nullable
              - optional
        postalCode:
          description: Postal code, or `null` when no address is stored.
          type:
            - string
            - 'null'
          example: '50667'
          x-mint:
            post:
              - nullable
              - optional
        city:
          description: City, or `null` when no address is stored.
          type:
            - string
            - 'null'
          example: Cologne
          x-mint:
            post:
              - nullable
              - optional
        countryCode:
          description: >-
            Uppercase two-character country or territory code, or `null` when no
            address is stored.
          type:
            - string
            - 'null'
          example: DE
          x-mint:
            post:
              - nullable
              - optional
        additionalInfo:
          description: >-
            Additional employee or address information, or `null` when none is
            stored.
          type:
            - string
            - 'null'
          example: Building B, third floor
          x-mint:
            post:
              - nullable
              - optional
        blocked:
          type: boolean
          description: Whether the employee account is blocked.
          example: false
        tenant:
          description: >-
            Tenant identifier, or `null` if the employee has no tenant
            assignment.
          readOnly: true
          type:
            - string
            - 'null'
          minLength: 1
          pattern: ^[0-9a-fA-F]{24}$
          example: 68a000000000000000000010
          x-mint:
            post:
              - nullable
        divisionId:
          description: >-
            Assigned division identifier, or `null` when no division is
            assigned.
          type:
            - string
            - 'null'
          minLength: 1
          pattern: ^[0-9a-fA-F]{24}$
          example: 68920e08eeaea4f2301eecb3
          x-mint:
            post:
              - nullable
        createdAt:
          type: string
          description: UTC timestamp at which the employee record was created.
          pattern: Z$
          format: date-time
          readOnly: true
          minLength: 1
          example: '2026-06-01T08:00:00.000Z'
        updatedAt:
          type: string
          description: UTC timestamp of the latest employee update.
          pattern: Z$
          format: date-time
          readOnly: true
          minLength: 1
          example: '2026-07-15T11:30:00.000Z'
      description: Employee details.
      required:
        - id
        - email
        - blocked
        - tenant
        - divisionId
        - createdAt
        - updatedAt
      example:
        id: 68a000000000000000000001
        email: alex.morgan@example.com
        privateEmail: alex.morgan.private@example.net
        employeeNumber: EMP-1042
        firstName: Alex
        lastName: Morgan
        phoneNumber: +49 221 5550100
        street: Example Street 12
        postalCode: '50667'
        city: Cologne
        countryCode: DE
        additionalInfo: Building B, third floor
        blocked: false
        tenant: 68a000000000000000000010
        divisionId: 68920e08eeaea4f2301eecb3
        createdAt: '2026-06-01T08:00:00.000Z'
        updatedAt: '2026-07-15T11:30:00.000Z'
    ErrorResponse:
      type: object
      properties:
        error:
          allOf:
            - $ref: '#/components/schemas/ApiError'
            - type: object
              description: Public error details.
          description: Machine-readable and human-readable details for the failed request.
      example:
        error:
          code: INVALID_API_KEY
          message: The supplied API key is missing, invalid, or inactive.
          requestId: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
      description: Error envelope returned by every public API endpoint.
      required:
        - error
    ApiError:
      type: object
      properties:
        code:
          type: string
          example: INVALID_API_KEY
          description: >-
            Machine-readable public error code. Values are stable and
            case-sensitive.


            - `INVALID_API_KEY`: The API key is missing, invalid, inactive, or
            otherwise unusable.

            - `INVALID_REQUEST_ID`: X-Request-ID is not a valid UUID version 4
            or 7.

            - `NOT_ACCEPTABLE`: The Accept header excludes all success media
            types produced by the operation.

            - `UNSUPPORTED_MEDIA_TYPE`: The request Content-Type is not
            supported by the operation.

            - `MISSING_ATTACHMENT`: A required multipart attachment field or
            file is missing.

            - `PAYLOAD_TOO_LARGE`: The complete request body exceeds the
            documented 5 MiB limit.

            - `UNKNOWN_QUERY_PARAMETER`: The request contains a query parameter
            that the operation does not accept.

            - `UNSUPPORTED_HEADER`: The request contains a header value or
            header usage that the public contract does not support.

            - `NOT_FOUND`: The target resource does not exist or is not visible
            in the caller scope.

            - `FILE_NOT_FOUND`: The referenced file is not available.

            - `BAD_GATEWAY`: A downstream file or integration service failed
            while processing the request.

            - `SERVICE_UNAVAILABLE`: The requested service is temporarily
            unavailable.

            - `GATEWAY_TIMEOUT`: A downstream operation did not complete before
            the timeout.

            - `INTERNAL_SERVER_ERROR`: An unexpected server-side error occurred.

            - `TENANT_CONTEXT_AMBIGUOUS`: The API cannot infer exactly one
            tenant from the supplied selectors and API-key scope.

            - `EMPLOYEE_PLACEMENT_AMBIGUOUS`: The API cannot infer one permitted
            employee division placement.

            - `TENANT_NOT_IN_SCOPE`: The selected tenant is not accessible to
            the API key.

            - `INVALID_REFERENCE_ID`: A referenced identifier is invalid for the
            requested operation.

            - `VALIDATION_ERROR`: The request is malformed or a supplied value
            fails contract or business validation.

            - `INVALID_FILTER_SYNTAX`: The filter expression cannot be parsed.

            - `UNSUPPORTED_FILTER_FIELD`: The filter uses a field that the
            operation does not expose for filtering.

            - `UNSUPPORTED_FILTER_OPERATOR`: The filter uses an operator that is
            not supported for the selected field.

            - `UNSUPPORTED_SORT_FIELD`: The sort field is not supported by the
            operation.

            - `UNSUPPORTED_FIELD`: The request contains a field that is not
            accepted by the operation.

            - `INVALID_REFERENCE`: A referenced resource cannot be used in the
            requested context or scope.

            - `EMPLOYEE_BLOCKED`: The requested operation cannot continue
            because the employee account is blocked.

            - `DIVISION_CYCLE`: The requested parent relationship would create a
            division hierarchy cycle.

            - `DIVISION_NAME_NOT_UNIQUE_ON_SAME_LEVEL`: A sibling division
            already uses the requested name.

            - `DUPLICATE_RESOURCE`: The request would create or update a
            resource to a value that must be unique.

            - `INVALID_STATE_TRANSITION`: The requested action is not permitted
            from the resource current lifecycle state.

            - `ORDER_ALREADY_DECIDED`: The order already has an HR review
            decision and cannot be decided again.

            - `RATE_LIMIT_EXCEEDED`: The API-key request quota has been
            exceeded.
          enum:
            - INVALID_API_KEY
            - INVALID_REQUEST_ID
            - NOT_ACCEPTABLE
            - UNSUPPORTED_MEDIA_TYPE
            - MISSING_ATTACHMENT
            - PAYLOAD_TOO_LARGE
            - UNKNOWN_QUERY_PARAMETER
            - UNSUPPORTED_HEADER
            - NOT_FOUND
            - FILE_NOT_FOUND
            - BAD_GATEWAY
            - SERVICE_UNAVAILABLE
            - GATEWAY_TIMEOUT
            - INTERNAL_SERVER_ERROR
            - TENANT_CONTEXT_AMBIGUOUS
            - EMPLOYEE_PLACEMENT_AMBIGUOUS
            - TENANT_NOT_IN_SCOPE
            - INVALID_REFERENCE_ID
            - VALIDATION_ERROR
            - INVALID_FILTER_SYNTAX
            - UNSUPPORTED_FILTER_FIELD
            - UNSUPPORTED_FILTER_OPERATOR
            - UNSUPPORTED_SORT_FIELD
            - UNSUPPORTED_FIELD
            - INVALID_REFERENCE
            - EMPLOYEE_BLOCKED
            - DIVISION_CYCLE
            - DIVISION_NAME_NOT_UNIQUE_ON_SAME_LEVEL
            - DUPLICATE_RESOURCE
            - INVALID_STATE_TRANSITION
            - ORDER_ALREADY_DECIDED
            - RATE_LIMIT_EXCEEDED
          minLength: 1
        message:
          type: string
          example: The supplied API key is missing, invalid, or inactive.
          description: Human-readable error summary.
          minLength: 1
        requestId:
          type: string
          example: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
          description: >-
            Request identifier also returned in the X-Request-ID response
            header.
          pattern: >-
            ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[47][0-9a-fA-F]{3}-[89aAbB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$
          format: uuid
          minLength: 1
      description: Stable public API error details.
      required:
        - code
        - message
        - requestId
      example:
        code: VALIDATION_ERROR
        message: The request contains an invalid value.
        requestId: 018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      name: X-API-Key
      in: header
      description: >-
        JobHandy integration API key. Send the credential in the `X-API-Key`
        header. Treat the key as a secret and use it only from trusted
        server-side environments.

````