OfficeGest
Workshop/Appointments/Plan

Plan appointment segments

Proposes the segments of an appointment without writing anything. Accepts the classic body (start, end, employee_id, department_id, interventions) or the grouped one (groups). With a mechanic the windows are the business hours minus their appointments up to the concurrency limit; with only a department, the business hours; with neither, the appointment is not split. Holidays, non-business days, vacations and absences cut according to the agenda restrictions. A plan that exceeds max_segments or max_spill_days, or for which no window serves, is rejected with 422 and data.errors.plan.limit (max_segments, max_spill_days, no_window) plus group_index for the grouped body. In the grouped body each group may carry its own allow_split, which wins over the one of the request; every planned appointment returns the allow_split it was laid with. The client only asks for a plan when the split_planning_enabled agenda parameter is on.

POST
/workshop/appointments/plan
AuthorizationBearer <token>

In: header

allow_splitboolean

true lays the work across the next windows; false pushes it whole into the first window that holds it. In the grouped body, the option of every group that does not carry its own.

startstring

Classic body: requested start, Y-m-d H:i. Required without groups.

Formatdate-time
endstring

Classic body: requested end, Y-m-d H:i; end - start is the work to plan.

Formatdate-time
employee_id?integer | null

Mechanic: windows come from the business hours and their appointments, up to the concurrency limit.

department_id?integer | null

Department, used when there is no mechanic: windows come from the business hours only.

interventions?array<object>

Planned in the order received; each with id and optional time in minutes (else the catalogue estimate).

groups?array<unknown>

Grouped body: one appointment per group, each with start, end, employee_id, department_id, interventions and an optional allow_split that wins over the one of the request. After the first, each group starts where the previous one's last segment ends, as laid with that group's option.

simultaneous?boolean

Grouped body: every group starts at reception_date and their segments may overlap.

reception_date?string

Vehicle reception, Y-m-d H:i. Required when simultaneous is true.

Response Body

curl -X POST "https://og-tenant1.test:8003/api/v2/workshop/appointments/plan" \
  -H "Content-Type: application/json" \
  -d '{
    "allow_split": true,
    "start": "2026-10-06 17:00",
    "end": "2026-10-06 19:00"
  }'
{
  "data": {
    "appointments": [
      {
        "start": "2019-08-24T14:15:22Z",
        "end": "2019-08-24T14:15:22Z",
        "allow_split": true,
        "segments": [
          {
            "start": "2019-08-24T14:15:22Z",
            "end": "2019-08-24T14:15:22Z",
            "interventions": [
              {
                "intervention_id": 0,
                "minutes": 0
              }
            ]
          }
        ]
      }
    ]
  }
}
{
  "data": {
    "code": "VALIDATION_FAILED",
    "message": "The given data was invalid.",
    "errors": {
      "email": [
        "The email field is required."
      ]
    }
  },
  "meta": {
    "trace_id": "9f86d081884c7d659a2feaa0c55ad01568f3a1c2b4d5e"
  }
}
{
  "data": {
    "code": "VALIDATION_FAILED",
    "message": "The given data was invalid.",
    "errors": {
      "email": [
        "The email field is required."
      ]
    }
  },
  "meta": {
    "trace_id": "9f86d081884c7d659a2feaa0c55ad01568f3a1c2b4d5e"
  }
}
{
  "data": {
    "code": "VALIDATION_FAILED",
    "message": "The given data was invalid.",
    "errors": {
      "email": [
        "The email field is required."
      ]
    }
  },
  "meta": {
    "trace_id": "9f86d081884c7d659a2feaa0c55ad01568f3a1c2b4d5e"
  }
}
{
  "data": {
    "code": "VALIDATION_FAILED",
    "message": "The given data was invalid.",
    "errors": {
      "email": [
        "The email field is required."
      ]
    }
  },
  "meta": {
    "trace_id": "9f86d081884c7d659a2feaa0c55ad01568f3a1c2b4d5e"
  }
}