> ## Documentation Index
> Fetch the complete documentation index at: https://jobticket-docs.ticket-plus.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Trigger HR Sync

> Push the current employee roster from your HR system to JobTicket.

Submits your complete current employee roster to JobTicket. The API performs a full reconciliation — adding new employees, updating changed records, and offboarding employees no longer in the list.

<Note>
  This endpoint is only available for HR integrations of type **API Integration**. Attempting to trigger a sync on an integration of any other type will return a `422 Unprocessable Entity` error.
</Note>

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url "https://v1-api.ticket-plus.app/hr-integrations/7/sync" \
    --header "Authorization: Basic <base64(clientId:clientSecret)>" \
    --header "Content-Type: application/json" \
    --data '{
      "syncId": "sync-2024-05-14-001",
      "employees": [
        {
          "firstName": "Anna",
          "lastName": "Müller",
          "email": "anna.mueller@example.com",
          "profileImage": null,
          "dateOfBirth": "1990-04-15",
          "hrId": "emp_HR_001",
          "startDate": "2022-03-01",
          "terminationDate": null,
          "autoSyncEmployee": null,
          "absences": []
        }
      ]
    }'
  ```

  ```python Python theme={null}
  import requests, base64

  credentials = base64.b64encode(b"<clientId>:<clientSecret>").decode()

  res = requests.post(
      "https://v1-api.ticket-plus.app/hr-integrations/7/sync",
      headers={
          "Authorization": f"Basic {credentials}",
          "Content-Type": "application/json",
      },
      json={
          "syncId": "sync-2024-05-14-001",
          "employees": [
              {
                  "firstName": "Anna",
                  "lastName": "Müller",
                  "email": "anna.mueller@example.com",
                  "profileImage": None,
                  "dateOfBirth": "1990-04-15",
                  "hrId": "emp_HR_001",
                  "startDate": "2022-03-01",
                  "terminationDate": None,
                  "autoSyncEmployee": None,
                  "absences": [],
              }
          ],
      },
  )
  print(res.status_code)  # 204
  ```

  ```javascript Node.js theme={null}
  const credentials = Buffer.from("<clientId>:<clientSecret>").toString("base64");

  const res = await fetch(
    "https://v1-api.ticket-plus.app/hr-integrations/7/sync",
    {
      method: "POST",
      headers: {
        Authorization: `Basic ${credentials}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        syncId: "sync-2024-05-14-001",
        employees: [
          {
            firstName: "Anna",
            lastName: "Müller",
            email: "anna.mueller@example.com",
            profileImage: null,
            dateOfBirth: "1990-04-15",
            hrId: "emp_HR_001",
            startDate: "2022-03-01",
            terminationDate: null,
            autoSyncEmployee: null,
            absences: [],
          },
        ],
      }),
    },
  );
  console.log(res.status); // 204
  ```
</RequestExample>

<ResponseExample>
  ```http 204 No Content theme={null}
  (empty body)
  ```
</ResponseExample>

<Warning>
  This is a **full-roster replace** operation. Any employee omitted from the
  `employees` array will be **offboarded** in JobTicket. Always include every
  currently active employee in the payload.
</Warning>

## Path Parameters

<ParamField path="id" type="number" required>
  The unique numeric ID of the HR integration to sync against. Must refer to an integration of type **API Integration**. Obtain this from
  [List HR Integrations](/v1/endpoint/hr-integrations-list).
</ParamField>

## Body

<ParamField body="syncId" type="string" required>
  A unique identifier for this sync operation. Used for idempotency and audit
  logging. Use a UUID or timestamp-based string. Re-submitting with the same
  `syncId` is safe — duplicate submissions will be deduplicated.
</ParamField>

<ParamField body="employees" type="object[]" required>
  The **complete** current employee roster from your HR system. Must contain at least one employee. Employees absent from this list will be offboarded in JobTicket.

  <Expandable title="employee object">
    <ParamField body="firstName" type="string" required>
      Employee's first name.
    </ParamField>

    <ParamField body="lastName" type="string" required>
      Employee's last name.
    </ParamField>

    <ParamField body="email" type="string" required>
      Employee's work email address. Used to match against existing JobTicket accounts.
    </ParamField>

    <ParamField body="profileImage" type="string | null" required>
      URL to the employee's profile photo. Pass `null` if not available.
    </ParamField>

    <ParamField body="dateOfBirth" type="string" required>
      Date of birth in `YYYY-MM-DD` format.
    </ParamField>

    <ParamField body="hrId" type="string" required>
      The employee's unique identifier in your HR system. Used to match records across syncs — must be **stable** and **never reused** for a different person.
    </ParamField>

    <ParamField body="startDate" type="string" required>
      Employment start date in `YYYY-MM-DD` format.
    </ParamField>

    <ParamField body="terminationDate" type="string | null" required>
      Termination date in `YYYY-MM-DD` format. Set this when the employee is leaving the company or has been deleted from your HR system. Pass `null` if the employee is still active.
    </ParamField>

    <ParamField body="autoSyncEmployee" type="boolean | null" required>
      Controls whether this employee is automatically included in future scheduled syncs. This field is only relevant if you have configured a **custom field in your HR system** to manage employee subscription eligibility — in that case, pass `true` or `false` based on the custom field value. If you are not using a custom field to control subscriptions, this field is not applicable and should be set to `null`.
    </ParamField>

    <ParamField body="absences" type="object[]" required>
      Current absences for this employee. Pass an empty array `[]` if there are none.

      <Expandable title="absence object">
        <ParamField body="absenceTypeId" type="string" required>
          The unique ID of the absence type as it exists in your HR system. This is an opaque identifier — pass the raw ID your HR system assigns to the absence type, without mapping or transforming it.
        </ParamField>

        <ParamField body="absenceId" type="string" required>
          Unique identifier for this specific absence record in your HR system.
        </ParamField>

        <ParamField body="fromDate" type="string" required>
          Absence start date in `YYYY-MM-DD` format.
        </ParamField>

        <ParamField body="toDate" type="string" required>
          Absence end date in `YYYY-MM-DD` format.
        </ParamField>

        <ParamField body="active" type="boolean" required>
          Set to `true` if the absence has been approved. Set to `false` if the absence has been rejected or deleted from your HR system.
        </ParamField>
      </Expandable>
    </ParamField>
  </Expandable>
</ParamField>

## Response

<ResponseField name="(empty body)" type="null">
  **`204 No Content`** — The sync has been accepted and will process in the
  background. The response body is empty.
</ResponseField>


## OpenAPI

````yaml POST /hr-integrations/{id}/sync
openapi: 3.0.3
info:
  title: JobTicket API
  description: >-
    The JobTicket B2B API lets you read employee data, manage HR integrations,
    and access employee documents programmatically. All endpoints use HTTP Basic
    Auth — pass your API key credentials from the Developer Portal as the
    username and password.
  version: 1.0.0
servers:
  - url: https://v1-api-staging.ticket-plus.app
    description: Staging server
  - url: https://v1-api.ticket-plus.app
    description: Production Server
security:
  - basicAuth: []
externalDocs:
  url: https://jobticket-docs.ticket-plus.app
  description: View our documentation to get more info
paths:
  /hr-integrations/{id}/sync:
    post:
      tags:
        - HR Integrations
      summary: Trigger HR Integration Sync
      description: >-
        Push the current employee roster from your HR system to JobTicket. The
        API reconciles the difference — adding new employees, updating changed
        records, and offboarding employees no longer in the list. Only call this
        when `canTriggerSync` is `true` on the integration. This is a
        fire-and-forget operation — a `204` response confirms the sync has been
        accepted and will process in the background.
      parameters:
        - schema:
            type: number
          in: path
          name: id
          required: true
          description: The unique numeric ID of the HR integration to sync against.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - syncId
                - employees
              properties:
                syncId:
                  type: string
                  description: >-
                    A unique identifier for this sync operation. Used for
                    idempotency and audit logging. Use a UUID or timestamp-based
                    string.
                employees:
                  type: array
                  minItems: 1
                  description: >-
                    The **complete** current employee roster from your HR
                    system. Must contain at least one employee. Employees absent
                    from this list will be offboarded in JobTicket.
                  items:
                    type: object
                    required:
                      - firstName
                      - lastName
                      - email
                      - profileImage
                      - dateOfBirth
                      - hrId
                      - startDate
                      - terminationDate
                      - autoSyncEmployee
                      - absences
                    properties:
                      firstName:
                        type: string
                        description: Employee's first name.
                      lastName:
                        type: string
                        description: Employee's last name.
                      email:
                        type: string
                        format: email
                        description: >-
                          Employee's work email address. Used to match against
                          existing JobTicket accounts.
                      profileImage:
                        type: string
                        format: uri
                        nullable: true
                        description: URL to the employee's profile photo, or `null`.
                      dateOfBirth:
                        type: string
                        format: date
                        description: Date of birth in `YYYY-MM-DD` format.
                      hrId:
                        type: string
                        description: >-
                          The employee's unique identifier in your HR system.
                          Used to match records across syncs — must be stable
                          and not reused.
                      startDate:
                        type: string
                        format: date
                        description: Employment start date in `YYYY-MM-DD` format.
                      terminationDate:
                        type: string
                        format: date
                        nullable: true
                        description: >-
                          Termination date in `YYYY-MM-DD` format. Pass `null`
                          if the employee is still active.
                      autoSyncEmployee:
                        type: boolean
                        nullable: true
                        description: >-
                          If `true`, this employee will be automatically
                          included in future scheduled syncs from the HR system.
                      absences:
                        type: array
                        description: >-
                          Current absences for this employee. Pass an empty
                          array if there are none.
                        items:
                          type: object
                          required:
                            - absenceTypeId
                            - absenceId
                            - fromDate
                            - toDate
                            - active
                          properties:
                            absenceTypeId:
                              type: string
                              description: >-
                                Identifier for the type of absence in your HR
                                system .
                            absenceId:
                              type: string
                              description: >-
                                Unique identifier for this absence record in
                                your HR system.
                            fromDate:
                              type: string
                              format: date
                              description: Absence start date in `YYYY-MM-DD` format.
                            toDate:
                              type: string
                              format: date
                              description: Absence end date in `YYYY-MM-DD` format.
                            active:
                              type: boolean
                              description: '`true` if this absence is currently active.'
                          additionalProperties: false
                    additionalProperties: false
              additionalProperties: false
      responses:
        '204':
          description: >-
            Sync accepted and will process in the background. The response body
            is empty.
          content:
            application/json:
              schema:
                description: Empty body on success.
      security:
        - basicAuth: []
components:
  securitySchemes:
    basicAuth:
      type: http
      scheme: basic
      description: >-
        HTTP Basic Auth using your API key credentials. Use the username and
        password issued from the Developer Portal. Encode them as
        `Base64(username:password)` and pass in the `Authorization: Basic
        <token>` header.

````