Employees

The people who can be sent to jobs (personal), their weekly working hours and their skills. Sync them from an HR or payroll system; match on employee_number.

List employees

GET/employees

Employees by last name, then first name, with their skills and linked login. For an HR or payroll sync, match on employee_number. Cursor-paginated: follow links.next, or pass meta.next_cursor as cursor.

curl 'https://api.closepact.com/v1/api/employees' \
  -H "Authorization: Bearer $CLOSEPACT_API_KEY"
Response · 200
{
  "data": [
    {
      "id": "01a15b90-1f2e-7a3b-8c4d-5e6f7a8b9c01",
      "employee_number": "A-017",
      "first_name": "Ali",
      "last_name": "Hassan",
      "name": "Ali Hassan",
      "email": "ali.hassan@nordiskfastighet.se",
      "phone": "073-981 22 40",
      "employment_type": "employed",
      "weekly_hours": 40,
      "hourly_cost_cents": 32000,
      "hourly_billing_rate_cents": 65000,
      "color": "#2F80ED",
      "status": "active",
      "started_at": "2024-03-01",
      "ended_at": null,
      "user": {
        "id": "01a14eb3-c6a1-7e2f-8a3b-4c5d6e7f8091",
        "name": "Ali Hassan",
        "email": "ali.hassan@nordiskfastighet.se"
      },
      "skills": [
        {
          "id": "01a15b70-7c8d-7e9f-a0b1-c2d3e4f50617",
          "name": "Storstädning",
          "color": "#27AE60",
          "level": 3
        }
      ],
      "created_at": "2024-02-20T08:30:00+00:00",
      "updated_at": "2026-10-01T12:00:00+00:00"
    }
  ],
  "links": {
    "first": null,
    "last": null,
    "prev": null,
    "next": null
  },
  "meta": {
    "path": "https://api.closepact.com/v1/api/employees",
    "per_page": 25,
    "next_cursor": null,
    "prev_cursor": null
  }
}

Query parameters

  • qstring

    Search in first name, last name and employee number (case-insensitive, substring).

    Example Hassan

  • filter[status]string

    Only active or only inactive employees.

    One ofactiveinactive

  • filter[skill_id]string(uuid)

    Only employees holding this skill.

  • limitinteger

    Items per page, 1–100.

    Default 251–100

  • cursorstring

    Opaque cursor from meta.next_cursor or meta.prev_cursor of the previous page.

Responses

  • Headers

    • X-RateLimit-Limit — Requests this key may make per minute.
    • X-RateLimit-Remaining — Requests left in the current minute.
    • dataarray of objectsrequired
      • idstring(uuid)required

        The employee id.

      • employee_numberstringnullablerequired

        Your own number for them (e.g. from payroll), or null.

      • first_namestringrequired

        First name.

      • last_namestringrequired

        Last name.

      • namestringrequired

        First and last name.

      • emailstringnullablerequired

        Email address; assignments are emailed here. Null for none.

      • phonestringnullablerequired

        Phone number as entered; used for SMS notices when the organization has turned them on.

      • employment_typestringrequired

        Kind of employment.

        One ofemployedhourlycontractor

      • weekly_hoursnumbernullablerequired

        Contracted hours per week, or null.

      • hourly_cost_centsintegernullablerequired

        What an hour of this person costs the company, in öre (not what it is sold for). Copied onto time entries as hourly_rate_cents when they are approved, for margin; never invoiced.

      • hourly_billing_rate_centsintegernullablerequired

        What an hour of this person is invoiced at, in öre excluding VAT. Copied onto time entries as billing_rate_cents when they are approved; the invoice basis bills hourly work at it unless the job was quoted one service price per hour. Null: such hours are billed at nothing and the basis warns.

      • colorstringnullablerequired

        Colour on the board, e.g. #2F80ED, or null.

      • statusstringrequired

        Inactive employees stay on past jobs and timesheets but cannot be scheduled without a not_employed error.

        One ofactiveinactive

      • started_atstring(date)nullablerequired

        First day of employment, or null. Calendar date, YYYY-MM-DD.

      • ended_atstring(date)nullablerequired

        Last day of employment, or null. Calendar date, YYYY-MM-DD.

      • userobjectnullable

        The member login this employee is linked to, or null. Included by the list and GET /employees/{employee}.

      • skillsarray of objectsrequired

        Competences the employee holds. A service that requires competences can only be done by somebody holding them all.

      • availabilityarray of objects

        Weekly working hours. Included by GET /employees/{employee} only; also at GET /employees/{employee}/availability.

      • created_atstring(date-time)required

        ISO 8601 date-time, in UTC.

      • updated_atstring(date-time)required

        ISO 8601 date-time, in UTC.

    • linksobjectrequired
    • metaobjectrequired
  • 401No key, or the key is invalid, revoked or expired, or its creator no longer has access.
    Errors
  • 402The organization has not bought the module this endpoint belongs to, or it has lapsed to read-only, or its tier does not include what the operation needs: feature names the capability (the operation's x-feature) and required_tier the cheapest tier that grants it. Every operation answers this with "feature": "core.api" when no module the organization holds is on a tier that includes the API.
    Errors
  • 403The key lacks the scope, or the member it acts as lacks the permission or holds no seat in the module (module_seat_required — an administrator assigns seats under Settings → Users), or the organization is suspended.
    Errors
  • 429The key has made more requests this minute than its limit allows.
    Errors

Create an employee

POST/employees
Scope write Module Scheduling & work orders Permission booking.resources.manage

Adds somebody who can be scheduled — from an HR system, say. An employee does not need a login and does not use a licence; link one with user_id if they should see their own jobs in the field app.

curl -X POST 'https://api.closepact.com/v1/api/employees' \
  -H "Authorization: Bearer $CLOSEPACT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "first_name": "Ali",
  "last_name": "Hassan",
  "employee_number": "A-017",
  "email": "ali.hassan@nordiskfastighet.se",
  "phone": "073-981 22 40",
  "employment_type": "employed",
  "hourly_cost_cents": 32000,
  "hourly_billing_rate_cents": 65000,
  "weekly_hours": 40,
  "started_at": "2024-03-01",
  "skill_ids": [
    "01a15b70-7c8d-7e9f-a0b1-c2d3e4f50617"
  ]
}'
Response · 201
{
  "data": {
    "id": "01a15b90-1f2e-7a3b-8c4d-5e6f7a8b9c01",
    "employee_number": "A-017",
    "first_name": "Ali",
    "last_name": "Hassan",
    "name": "Ali Hassan",
    "email": "ali.hassan@nordiskfastighet.se",
    "phone": "073-981 22 40",
    "employment_type": "employed",
    "weekly_hours": 40,
    "hourly_cost_cents": 32000,
    "hourly_billing_rate_cents": 65000,
    "color": "#2F80ED",
    "status": "active",
    "started_at": "2024-03-01",
    "ended_at": null,
    "skills": [
      {
        "id": "01a15b70-7c8d-7e9f-a0b1-c2d3e4f50617",
        "name": "Storstädning",
        "color": "#27AE60",
        "level": 3
      }
    ],
    "created_at": "2024-02-20T08:30:00+00:00",
    "updated_at": "2026-10-01T12:00:00+00:00"
  }
}

Request body

application/json · required

  • first_namestringrequired

    First name.

    at most 128 characters

  • last_namestringrequired

    Last name.

    at most 128 characters

  • employee_numberstringnullable

    Your own number for them, e.g. the payroll id.

    at most 32 characters

  • emailstring(email)nullable

    Email address for assignment notices.

    at most 320 characters

  • phonestringnullable

    Phone number.

    at most 32 characters

  • employment_typestring

    Default employed.

    One ofemployedhourlycontractor

  • hourly_cost_centsintegernullable

    Cost of an hour of this person in öre — wage and overheads, never invoiced.

    ≥ 0

  • hourly_billing_rate_centsintegernullable

    What an hour of this person is invoiced at, in öre excluding VAT. An hourly job bills this person's approved time at it when the job was not quoted one service price per hour.

    ≥ 0

  • weekly_hoursnumbernullable

    Contracted hours per week, 0–168.

    0–168

  • colorstringnullable

    Colour on the board, e.g. #2F80ED.

    at most 16 characters

  • statusstring

    Default active.

    One ofactiveinactive

  • started_atstring(date)nullable

    First day of employment. Calendar date, YYYY-MM-DD.

  • ended_atstring(date)nullable

    Last day of employment; not before started_at. Calendar date, YYYY-MM-DD.

  • user_idstring(uuid)nullable

    Link to the login of a member of your organization (an active member), or null for none.

  • sub_entity_idstring(uuid)nullable

    The office (sub-entity) the employee belongs to. Must be one of yours.

  • skill_idsarray of strings(uuid)

    Replaces the employee's skills with these (see GET /skills). Ids that are not your organization's are ignored. Leave out to keep the current skills; [] removes them all. A skill the employee already holds keeps its level; a new one starts at 1. To set levels, send skills instead.

  • skillsarray of objects

    Replaces the employee's skills with these, each with a level. Same rules as skill_ids, which it cannot be sent together with. A skill sent without level is level 1.

Responses

  • Headers

    • X-RateLimit-Limit — Requests this key may make per minute.
    • X-RateLimit-Remaining — Requests left in the current minute.
    • dataobjectrequired

      Somebody who can be sent to a job (personal). Not the same as a member of the organization: an employee may be linked to a member's login (user) but need not be — field staff who never sign in are scheduled without using a licence.

      • idstring(uuid)required

        The employee id.

      • employee_numberstringnullablerequired

        Your own number for them (e.g. from payroll), or null.

      • first_namestringrequired

        First name.

      • last_namestringrequired

        Last name.

      • namestringrequired

        First and last name.

      • emailstringnullablerequired

        Email address; assignments are emailed here. Null for none.

      • phonestringnullablerequired

        Phone number as entered; used for SMS notices when the organization has turned them on.

      • employment_typestringrequired

        Kind of employment.

        One ofemployedhourlycontractor

      • weekly_hoursnumbernullablerequired

        Contracted hours per week, or null.

      • hourly_cost_centsintegernullablerequired

        What an hour of this person costs the company, in öre (not what it is sold for). Copied onto time entries as hourly_rate_cents when they are approved, for margin; never invoiced.

      • hourly_billing_rate_centsintegernullablerequired

        What an hour of this person is invoiced at, in öre excluding VAT. Copied onto time entries as billing_rate_cents when they are approved; the invoice basis bills hourly work at it unless the job was quoted one service price per hour. Null: such hours are billed at nothing and the basis warns.

      • colorstringnullablerequired

        Colour on the board, e.g. #2F80ED, or null.

      • statusstringrequired

        Inactive employees stay on past jobs and timesheets but cannot be scheduled without a not_employed error.

        One ofactiveinactive

      • started_atstring(date)nullablerequired

        First day of employment, or null. Calendar date, YYYY-MM-DD.

      • ended_atstring(date)nullablerequired

        Last day of employment, or null. Calendar date, YYYY-MM-DD.

      • userobjectnullable

        The member login this employee is linked to, or null. Included by the list and GET /employees/{employee}.

      • skillsarray of objectsrequired

        Competences the employee holds. A service that requires competences can only be done by somebody holding them all.

      • availabilityarray of objects

        Weekly working hours. Included by GET /employees/{employee} only; also at GET /employees/{employee}/availability.

      • created_atstring(date-time)required

        ISO 8601 date-time, in UTC.

      • updated_atstring(date-time)required

        ISO 8601 date-time, in UTC.

  • 401No key, or the key is invalid, revoked or expired, or its creator no longer has access.
    Errors
  • 402The organization has not bought the module this endpoint belongs to, or it has lapsed to read-only, or its tier does not include what the operation needs: feature names the capability (the operation's x-feature) and required_tier the cheapest tier that grants it. Every operation answers this with "feature": "core.api" when no module the organization holds is on a tier that includes the API.
    Errors
  • 403The key lacks the scope, or the member it acts as lacks the permission or holds no seat in the module (module_seat_required — an administrator assigns seats under Settings → Users), or the organization is suspended.
    Errors
  • 422The request body or query failed validation.
    Errors
  • 429The key has made more requests this minute than its limit allows.
    Errors

Get an employee

GET/employees/{employee}

One employee with skills, linked login and weekly availability. A deleted employee, or another organization's, is a 404.

curl 'https://api.closepact.com/v1/api/employees/01a14f2c-7c1e-7d0b-9a3e-3f5b2c8d1e40' \
  -H "Authorization: Bearer $CLOSEPACT_API_KEY"
Response · 200
{
  "data": {
    "id": "01a15b90-1f2e-7a3b-8c4d-5e6f7a8b9c01",
    "employee_number": "A-017",
    "first_name": "Ali",
    "last_name": "Hassan",
    "name": "Ali Hassan",
    "email": "ali.hassan@nordiskfastighet.se",
    "phone": "073-981 22 40",
    "employment_type": "employed",
    "weekly_hours": 40,
    "hourly_cost_cents": 32000,
    "hourly_billing_rate_cents": 65000,
    "color": "#2F80ED",
    "status": "active",
    "started_at": "2024-03-01",
    "ended_at": null,
    "user": {
      "id": "01a14eb3-c6a1-7e2f-8a3b-4c5d6e7f8091",
      "name": "Ali Hassan",
      "email": "ali.hassan@nordiskfastighet.se"
    },
    "skills": [
      {
        "id": "01a15b70-7c8d-7e9f-a0b1-c2d3e4f50617",
        "name": "Storstädning",
        "color": "#27AE60",
        "level": 3
      }
    ],
    "availability": [
      {
        "id": "01a15b91-2a3b-7c4d-8e5f-60718293a4b5",
        "organization_id": "01a14eb3-c5f0-7c55-8c2e-6a0e1f7b9d21",
        "employee_id": "01a15b90-1f2e-7a3b-8c4d-5e6f7a8b9c01",
        "weekday": 1,
        "start_time": "07:00:00",
        "end_time": "11:30:00",
        "valid_from": "2026-01-01T00:00:00.000000Z",
        "valid_to": null,
        "created_at": "2025-12-18T10:00:00.000000Z",
        "updated_at": "2025-12-18T10:00:00.000000Z"
      },
      {
        "id": "01a15b91-2a3c-7d5e-9f60-718293a4b5c6",
        "organization_id": "01a14eb3-c5f0-7c55-8c2e-6a0e1f7b9d21",
        "employee_id": "01a15b90-1f2e-7a3b-8c4d-5e6f7a8b9c01",
        "weekday": 1,
        "start_time": "12:15:00",
        "end_time": "16:00:00",
        "valid_from": "2026-01-01T00:00:00.000000Z",
        "valid_to": null,
        "created_at": "2025-12-18T10:00:00.000000Z",
        "updated_at": "2025-12-18T10:00:00.000000Z"
      }
    ],
    "created_at": "2024-02-20T08:30:00+00:00",
    "updated_at": "2026-10-01T12:00:00+00:00"
  }
}

Path parameters

  • employeestring(uuid)required

    The employee id.

Responses

  • Headers

    • X-RateLimit-Limit — Requests this key may make per minute.
    • X-RateLimit-Remaining — Requests left in the current minute.
    • dataobjectrequired

      Somebody who can be sent to a job (personal). Not the same as a member of the organization: an employee may be linked to a member's login (user) but need not be — field staff who never sign in are scheduled without using a licence.

      • idstring(uuid)required

        The employee id.

      • employee_numberstringnullablerequired

        Your own number for them (e.g. from payroll), or null.

      • first_namestringrequired

        First name.

      • last_namestringrequired

        Last name.

      • namestringrequired

        First and last name.

      • emailstringnullablerequired

        Email address; assignments are emailed here. Null for none.

      • phonestringnullablerequired

        Phone number as entered; used for SMS notices when the organization has turned them on.

      • employment_typestringrequired

        Kind of employment.

        One ofemployedhourlycontractor

      • weekly_hoursnumbernullablerequired

        Contracted hours per week, or null.

      • hourly_cost_centsintegernullablerequired

        What an hour of this person costs the company, in öre (not what it is sold for). Copied onto time entries as hourly_rate_cents when they are approved, for margin; never invoiced.

      • hourly_billing_rate_centsintegernullablerequired

        What an hour of this person is invoiced at, in öre excluding VAT. Copied onto time entries as billing_rate_cents when they are approved; the invoice basis bills hourly work at it unless the job was quoted one service price per hour. Null: such hours are billed at nothing and the basis warns.

      • colorstringnullablerequired

        Colour on the board, e.g. #2F80ED, or null.

      • statusstringrequired

        Inactive employees stay on past jobs and timesheets but cannot be scheduled without a not_employed error.

        One ofactiveinactive

      • started_atstring(date)nullablerequired

        First day of employment, or null. Calendar date, YYYY-MM-DD.

      • ended_atstring(date)nullablerequired

        Last day of employment, or null. Calendar date, YYYY-MM-DD.

      • userobjectnullable

        The member login this employee is linked to, or null. Included by the list and GET /employees/{employee}.

      • skillsarray of objectsrequired

        Competences the employee holds. A service that requires competences can only be done by somebody holding them all.

      • availabilityarray of objects

        Weekly working hours. Included by GET /employees/{employee} only; also at GET /employees/{employee}/availability.

      • created_atstring(date-time)required

        ISO 8601 date-time, in UTC.

      • updated_atstring(date-time)required

        ISO 8601 date-time, in UTC.

  • 401No key, or the key is invalid, revoked or expired, or its creator no longer has access.
    Errors
  • 402The organization has not bought the module this endpoint belongs to, or it has lapsed to read-only, or its tier does not include what the operation needs: feature names the capability (the operation's x-feature) and required_tier the cheapest tier that grants it. Every operation answers this with "feature": "core.api" when no module the organization holds is on a tier that includes the API.
    Errors
  • 403The key lacks the scope, or the member it acts as lacks the permission or holds no seat in the module (module_seat_required — an administrator assigns seats under Settings → Users), or the organization is suspended.
    Errors
  • 404No such record in this organization.
    Errors
  • 429The key has made more requests this minute than its limit allows.
    Errors

Update an employee

PATCH/employees/{employee}
Scope write Module Scheduling & work orders Permission booking.resources.manage

Changes the fields you send. To take somebody off the schedule but keep their history, set status to inactive (or ended_at) rather than deleting them.

curl -X PATCH 'https://api.closepact.com/v1/api/employees/01a14f2c-7c1e-7d0b-9a3e-3f5b2c8d1e40' \
  -H "Authorization: Bearer $CLOSEPACT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "070-123 45 67",
  "weekly_hours": 32
}'
Response · 200
{
  "data": {
    "id": "01a15b90-1f2e-7a3b-8c4d-5e6f7a8b9c01",
    "employee_number": "A-017",
    "first_name": "Ali",
    "last_name": "Hassan",
    "name": "Ali Hassan",
    "email": "ali.hassan@nordiskfastighet.se",
    "phone": "070-123 45 67",
    "employment_type": "employed",
    "weekly_hours": 32,
    "hourly_cost_cents": 32000,
    "hourly_billing_rate_cents": 65000,
    "color": "#2F80ED",
    "status": "active",
    "started_at": "2024-03-01",
    "ended_at": null,
    "skills": [
      {
        "id": "01a15b70-7c8d-7e9f-a0b1-c2d3e4f50617",
        "name": "Storstädning",
        "color": "#27AE60",
        "level": 3
      }
    ],
    "created_at": "2024-02-20T08:30:00+00:00",
    "updated_at": "2026-10-01T12:00:00+00:00"
  }
}

Path parameters

  • employeestring(uuid)required

    The employee id.

Request body

application/json · required

  • first_namestring

    First name.

    at most 128 characters

  • last_namestring

    Last name.

    at most 128 characters

  • employee_numberstringnullable

    Your own number for them, e.g. the payroll id.

    at most 32 characters

  • emailstring(email)nullable

    Email address for assignment notices.

    at most 320 characters

  • phonestringnullable

    Phone number.

    at most 32 characters

  • employment_typestring

    Default employed.

    One ofemployedhourlycontractor

  • hourly_cost_centsintegernullable

    Cost of an hour of this person in öre — wage and overheads, never invoiced.

    ≥ 0

  • hourly_billing_rate_centsintegernullable

    What an hour of this person is invoiced at, in öre excluding VAT. An hourly job bills this person's approved time at it when the job was not quoted one service price per hour.

    ≥ 0

  • weekly_hoursnumbernullable

    Contracted hours per week, 0–168.

    0–168

  • colorstringnullable

    Colour on the board, e.g. #2F80ED.

    at most 16 characters

  • statusstring

    Default active.

    One ofactiveinactive

  • started_atstring(date)nullable

    First day of employment. Calendar date, YYYY-MM-DD.

  • ended_atstring(date)nullable

    Last day of employment; not before started_at. Calendar date, YYYY-MM-DD.

  • user_idstring(uuid)nullable

    Link to the login of a member of your organization (an active member), or null for none.

  • sub_entity_idstring(uuid)nullable

    The office (sub-entity) the employee belongs to. Must be one of yours.

  • skill_idsarray of strings(uuid)

    Replaces the employee's skills with these (see GET /skills). Ids that are not your organization's are ignored. Leave out to keep the current skills; [] removes them all. A skill the employee already holds keeps its level; a new one starts at 1. To set levels, send skills instead.

  • skillsarray of objects

    Replaces the employee's skills with these, each with a level. Same rules as skill_ids, which it cannot be sent together with. A skill sent without level is level 1.

Responses

  • Headers

    • X-RateLimit-Limit — Requests this key may make per minute.
    • X-RateLimit-Remaining — Requests left in the current minute.
    • dataobjectrequired

      Somebody who can be sent to a job (personal). Not the same as a member of the organization: an employee may be linked to a member's login (user) but need not be — field staff who never sign in are scheduled without using a licence.

      • idstring(uuid)required

        The employee id.

      • employee_numberstringnullablerequired

        Your own number for them (e.g. from payroll), or null.

      • first_namestringrequired

        First name.

      • last_namestringrequired

        Last name.

      • namestringrequired

        First and last name.

      • emailstringnullablerequired

        Email address; assignments are emailed here. Null for none.

      • phonestringnullablerequired

        Phone number as entered; used for SMS notices when the organization has turned them on.

      • employment_typestringrequired

        Kind of employment.

        One ofemployedhourlycontractor

      • weekly_hoursnumbernullablerequired

        Contracted hours per week, or null.

      • hourly_cost_centsintegernullablerequired

        What an hour of this person costs the company, in öre (not what it is sold for). Copied onto time entries as hourly_rate_cents when they are approved, for margin; never invoiced.

      • hourly_billing_rate_centsintegernullablerequired

        What an hour of this person is invoiced at, in öre excluding VAT. Copied onto time entries as billing_rate_cents when they are approved; the invoice basis bills hourly work at it unless the job was quoted one service price per hour. Null: such hours are billed at nothing and the basis warns.

      • colorstringnullablerequired

        Colour on the board, e.g. #2F80ED, or null.

      • statusstringrequired

        Inactive employees stay on past jobs and timesheets but cannot be scheduled without a not_employed error.

        One ofactiveinactive

      • started_atstring(date)nullablerequired

        First day of employment, or null. Calendar date, YYYY-MM-DD.

      • ended_atstring(date)nullablerequired

        Last day of employment, or null. Calendar date, YYYY-MM-DD.

      • userobjectnullable

        The member login this employee is linked to, or null. Included by the list and GET /employees/{employee}.

      • skillsarray of objectsrequired

        Competences the employee holds. A service that requires competences can only be done by somebody holding them all.

      • availabilityarray of objects

        Weekly working hours. Included by GET /employees/{employee} only; also at GET /employees/{employee}/availability.

      • created_atstring(date-time)required

        ISO 8601 date-time, in UTC.

      • updated_atstring(date-time)required

        ISO 8601 date-time, in UTC.

  • 401No key, or the key is invalid, revoked or expired, or its creator no longer has access.
    Errors
  • 402The organization has not bought the module this endpoint belongs to, or it has lapsed to read-only, or its tier does not include what the operation needs: feature names the capability (the operation's x-feature) and required_tier the cheapest tier that grants it. Every operation answers this with "feature": "core.api" when no module the organization holds is on a tier that includes the API.
    Errors
  • 403The key lacks the scope, or the member it acts as lacks the permission or holds no seat in the module (module_seat_required — an administrator assigns seats under Settings → Users), or the organization is suspended.
    Errors
  • 404No such record in this organization.
    Errors
  • 422The request body or query failed validation.
    Errors
  • 429The key has made more requests this minute than its limit allows.
    Errors

Delete an employee

DELETE/employees/{employee}
Scope write Module Scheduling & work orders Permission booking.resources.manage

Removes the employee from lists and reads. Their name stays on past jobs and their hours on past timesheets. For somebody who has left, status: inactive is usually what you want.

curl -X DELETE 'https://api.closepact.com/v1/api/employees/01a14f2c-7c1e-7d0b-9a3e-3f5b2c8d1e40' \
  -H "Authorization: Bearer $CLOSEPACT_API_KEY"
Response · 200
{
  "deleted": true
}

Path parameters

  • employeestring(uuid)required

    The employee id.

Responses

  • Headers

    • X-RateLimit-Limit — Requests this key may make per minute.
    • X-RateLimit-Remaining — Requests left in the current minute.
    • deletedbooleanrequired

      One oftrue

  • 401No key, or the key is invalid, revoked or expired, or its creator no longer has access.
    Errors
  • 402The organization has not bought the module this endpoint belongs to, or it has lapsed to read-only, or its tier does not include what the operation needs: feature names the capability (the operation's x-feature) and required_tier the cheapest tier that grants it. Every operation answers this with "feature": "core.api" when no module the organization holds is on a tier that includes the API.
    Errors
  • 403The key lacks the scope, or the member it acts as lacks the permission or holds no seat in the module (module_seat_required — an administrator assigns seats under Settings → Users), or the organization is suspended.
    Errors
  • 404No such record in this organization.
    Errors
  • 429The key has made more requests this minute than its limit allows.
    Errors

List an employee's working hours

GET/employees/{employee}/availability

All of the employee's availability rules, by weekday and start time — the whole set, not a page. Rules that have expired (valid_to in the past) are included.

curl 'https://api.closepact.com/v1/api/employees/01a14f2c-7c1e-7d0b-9a3e-3f5b2c8d1e40/availability' \
  -H "Authorization: Bearer $CLOSEPACT_API_KEY"
Response · 200
{
  "data": [
    {
      "id": "01a15b91-2a3b-7c4d-8e5f-60718293a4b5",
      "organization_id": "01a14eb3-c5f0-7c55-8c2e-6a0e1f7b9d21",
      "employee_id": "01a15b90-1f2e-7a3b-8c4d-5e6f7a8b9c01",
      "weekday": 1,
      "start_time": "07:00:00",
      "end_time": "11:30:00",
      "valid_from": "2026-01-01T00:00:00.000000Z",
      "valid_to": null,
      "created_at": "2025-12-18T10:00:00.000000Z",
      "updated_at": "2025-12-18T10:00:00.000000Z"
    },
    {
      "id": "01a15b91-2a3c-7d5e-9f60-718293a4b5c6",
      "organization_id": "01a14eb3-c5f0-7c55-8c2e-6a0e1f7b9d21",
      "employee_id": "01a15b90-1f2e-7a3b-8c4d-5e6f7a8b9c01",
      "weekday": 1,
      "start_time": "12:15:00",
      "end_time": "16:00:00",
      "valid_from": "2026-01-01T00:00:00.000000Z",
      "valid_to": null,
      "created_at": "2025-12-18T10:00:00.000000Z",
      "updated_at": "2025-12-18T10:00:00.000000Z"
    }
  ]
}

Path parameters

  • employeestring(uuid)required

    The employee id.

Responses

  • Headers

    • X-RateLimit-Limit — Requests this key may make per minute.
    • X-RateLimit-Remaining — Requests left in the current minute.
    • dataarray of objectsrequired
      • idstring(uuid)required

        The rule id.

      • organization_idstring(uuid)required

        Your organization.

      • employee_idstring(uuid)required

        The employee.

      • weekdayintegerrequired

        ISO weekday: 1 = Monday … 7 = Sunday.

        1–7

      • start_timestringrequired

        Start, HH:MM:SS, in Swedish local time (Europe/Stockholm). Job times, which are UTC instants, are converted to that clock — and to its weekday — before they are compared with the rule.

      • end_timestringrequired

        End, HH:MM:SS, after the start.

      • valid_fromstring(date-time)nullablerequired

        First day the rule applies, as midnight UTC of that date (2026-01-01T00:00:00.000000Z), or null for always. Only the date counts: it is matched against the job's date in Swedish time.

      • valid_tostring(date-time)nullablerequired

        Last day the rule applies (the whole day), as midnight UTC of that date, or null for open-ended. Only the date counts: it is matched against the job's date in Swedish time.

      • created_atstring(date-time)required

        ISO 8601 date-time, in UTC.

      • updated_atstring(date-time)required

        ISO 8601 date-time, in UTC.

  • 401No key, or the key is invalid, revoked or expired, or its creator no longer has access.
    Errors
  • 402The organization has not bought the module this endpoint belongs to, or it has lapsed to read-only, or its tier does not include what the operation needs: feature names the capability (the operation's x-feature) and required_tier the cheapest tier that grants it. Every operation answers this with "feature": "core.api" when no module the organization holds is on a tier that includes the API.
    Errors
  • 403The key lacks the scope, or the member it acts as lacks the permission or holds no seat in the module (module_seat_required — an administrator assigns seats under Settings → Users), or the organization is suspended.
    Errors
  • 404No such record in this organization.
    Errors
  • 429The key has made more requests this minute than its limit allows.
    Errors

Add working hours

POST/employees/{employee}/availability
Scope write Module Scheduling & work orders Permission booking.resources.manage

Adds the hours an employee normally works on one weekday. The schedule warns (outside_working_hours) when a job falls outside them; it never refuses. A split shift is two rules on the same day; gaps of up to an hour between them count as one working day.

To change hours from a date, add a rule with valid_from and end the old one with valid_to, so earlier timesheets keep the hours they were planned against. An identical rule (same day, times and dates) is a 409; an end before the start is a 422.

curl -X POST 'https://api.closepact.com/v1/api/employees/01a14f2c-7c1e-7d0b-9a3e-3f5b2c8d1e40/availability' \
  -H "Authorization: Bearer $CLOSEPACT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "weekday": 1,
  "start_time": "07:00",
  "end_time": "11:30",
  "valid_from": "2026-01-01"
}'
Response
{
  "data": {
    "id": "01a15b91-2a3b-7c4d-8e5f-60718293a4b5",
    "organization_id": "01a14eb3-c5f0-7c55-8c2e-6a0e1f7b9d21",
    "employee_id": "01a15b90-1f2e-7a3b-8c4d-5e6f7a8b9c01",
    "weekday": 1,
    "start_time": "07:00:00",
    "end_time": "11:30:00",
    "valid_from": "2026-01-01T00:00:00.000000Z",
    "valid_to": null,
    "created_at": "2025-12-18T10:00:00.000000Z",
    "updated_at": "2025-12-18T10:00:00.000000Z"
  }
}

Path parameters

  • employeestring(uuid)required

    The employee id.

Request body

application/json · required

  • weekdayintegerrequired

    ISO weekday: 1 = Monday … 7 = Sunday.

    1–7

  • start_timestringrequired

    Start, HH:MM (or HH:MM:SS; seconds are dropped), in Swedish local time (Europe/Stockholm). Job times are converted to that clock before they are compared, so 07:00 means seven in the morning in Sweden, summer and winter.

    pattern ^\d{2}:\d{2}(:\d{2})?$

  • end_timestringrequired

    End, after the start (otherwise 422).

    pattern ^\d{2}:\d{2}(:\d{2})?$

  • valid_fromstring(date)nullable

    First day the rule applies, or null for always. Calendar date, YYYY-MM-DD.

  • valid_tostring(date)nullable

    Last day the rule applies, or null for open-ended; not before valid_from. Calendar date, YYYY-MM-DD.

Responses

  • Headers

    • X-RateLimit-Limit — Requests this key may make per minute.
    • X-RateLimit-Remaining — Requests left in the current minute.
    • dataobjectrequired

      Hours an employee normally works on one weekday. Several rules on one day are allowed (a split shift around lunch). An employee with no rules at all is treated as always available.

      • idstring(uuid)required

        The rule id.

      • organization_idstring(uuid)required

        Your organization.

      • employee_idstring(uuid)required

        The employee.

      • weekdayintegerrequired

        ISO weekday: 1 = Monday … 7 = Sunday.

        1–7

      • start_timestringrequired

        Start, HH:MM:SS, in Swedish local time (Europe/Stockholm). Job times, which are UTC instants, are converted to that clock — and to its weekday — before they are compared with the rule.

      • end_timestringrequired

        End, HH:MM:SS, after the start.

      • valid_fromstring(date-time)nullablerequired

        First day the rule applies, as midnight UTC of that date (2026-01-01T00:00:00.000000Z), or null for always. Only the date counts: it is matched against the job's date in Swedish time.

      • valid_tostring(date-time)nullablerequired

        Last day the rule applies (the whole day), as midnight UTC of that date, or null for open-ended. Only the date counts: it is matched against the job's date in Swedish time.

      • created_atstring(date-time)required

        ISO 8601 date-time, in UTC.

      • updated_atstring(date-time)required

        ISO 8601 date-time, in UTC.

  • 401No key, or the key is invalid, revoked or expired, or its creator no longer has access.
    Errors
  • 402The organization has not bought the module this endpoint belongs to, or it has lapsed to read-only, or its tier does not include what the operation needs: feature names the capability (the operation's x-feature) and required_tier the cheapest tier that grants it. Every operation answers this with "feature": "core.api" when no module the organization holds is on a tier that includes the API.
    Errors
  • 403The key lacks the scope, or the member it acts as lacks the permission or holds no seat in the module (module_seat_required — an administrator assigns seats under Settings → Users), or the organization is suspended.
    Errors
  • 404No such record in this organization.
    Errors
  • Errors
  • 422The request body or query failed validation.
    Errors
  • 429The key has made more requests this minute than its limit allows.
    Errors

Change working hours

PATCH/employees/{employee}/availability/{rule}
Scope write Module Scheduling & work orders Permission booking.resources.manage

Changes the fields you send; the result is checked as a whole (sending only end_time still has to end after the stored start). A rule of another employee is a 404.

curl -X PATCH 'https://api.closepact.com/v1/api/employees/01a14f2c-7c1e-7d0b-9a3e-3f5b2c8d1e40/availability/01a14f2c-7c1e-7d0b-9a3e-3f5b2c8d1e40' \
  -H "Authorization: Bearer $CLOSEPACT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "end_time": "11:00"
}'
Response
{
  "data": {
    "id": "01a15b91-2a3b-7c4d-8e5f-60718293a4b5",
    "organization_id": "01a14eb3-c5f0-7c55-8c2e-6a0e1f7b9d21",
    "employee_id": "01a15b90-1f2e-7a3b-8c4d-5e6f7a8b9c01",
    "weekday": 1,
    "start_time": "07:00:00",
    "end_time": "11:00:00",
    "valid_from": "2026-01-01T00:00:00.000000Z",
    "valid_to": null,
    "created_at": "2025-12-18T10:00:00.000000Z",
    "updated_at": "2025-12-18T10:00:00.000000Z"
  }
}

Path parameters

  • employeestring(uuid)required

    The employee id.

  • rulestring(uuid)required

    The availability rule id.

Request body

application/json · required

  • weekdayinteger

    ISO weekday: 1 = Monday … 7 = Sunday.

    1–7

  • start_timestring

    Start, HH:MM (or HH:MM:SS; seconds are dropped), in Swedish local time (Europe/Stockholm). Job times are converted to that clock before they are compared, so 07:00 means seven in the morning in Sweden, summer and winter.

    pattern ^\d{2}:\d{2}(:\d{2})?$

  • end_timestring

    End, after the start (otherwise 422).

    pattern ^\d{2}:\d{2}(:\d{2})?$

  • valid_fromstring(date)nullable

    First day the rule applies, or null for always. Calendar date, YYYY-MM-DD.

  • valid_tostring(date)nullable

    Last day the rule applies, or null for open-ended; not before valid_from. Calendar date, YYYY-MM-DD.

Responses

  • Headers

    • X-RateLimit-Limit — Requests this key may make per minute.
    • X-RateLimit-Remaining — Requests left in the current minute.
    • dataobjectrequired

      Hours an employee normally works on one weekday. Several rules on one day are allowed (a split shift around lunch). An employee with no rules at all is treated as always available.

      • idstring(uuid)required

        The rule id.

      • organization_idstring(uuid)required

        Your organization.

      • employee_idstring(uuid)required

        The employee.

      • weekdayintegerrequired

        ISO weekday: 1 = Monday … 7 = Sunday.

        1–7

      • start_timestringrequired

        Start, HH:MM:SS, in Swedish local time (Europe/Stockholm). Job times, which are UTC instants, are converted to that clock — and to its weekday — before they are compared with the rule.

      • end_timestringrequired

        End, HH:MM:SS, after the start.

      • valid_fromstring(date-time)nullablerequired

        First day the rule applies, as midnight UTC of that date (2026-01-01T00:00:00.000000Z), or null for always. Only the date counts: it is matched against the job's date in Swedish time.

      • valid_tostring(date-time)nullablerequired

        Last day the rule applies (the whole day), as midnight UTC of that date, or null for open-ended. Only the date counts: it is matched against the job's date in Swedish time.

      • created_atstring(date-time)required

        ISO 8601 date-time, in UTC.

      • updated_atstring(date-time)required

        ISO 8601 date-time, in UTC.

  • 401No key, or the key is invalid, revoked or expired, or its creator no longer has access.
    Errors
  • 402The organization has not bought the module this endpoint belongs to, or it has lapsed to read-only, or its tier does not include what the operation needs: feature names the capability (the operation's x-feature) and required_tier the cheapest tier that grants it. Every operation answers this with "feature": "core.api" when no module the organization holds is on a tier that includes the API.
    Errors
  • 403The key lacks the scope, or the member it acts as lacks the permission or holds no seat in the module (module_seat_required — an administrator assigns seats under Settings → Users), or the organization is suspended.
    Errors
  • 404No such record in this organization.
    Errors
  • Errors
  • 422The request body or query failed validation.
    Errors
  • 429The key has made more requests this minute than its limit allows.
    Errors

Remove working hours

DELETE/employees/{employee}/availability/{rule}
Scope write Module Scheduling & work orders Permission booking.resources.manage

Deletes the rule. An employee left with no rules is treated as always available.

curl -X DELETE 'https://api.closepact.com/v1/api/employees/01a14f2c-7c1e-7d0b-9a3e-3f5b2c8d1e40/availability/01a14f2c-7c1e-7d0b-9a3e-3f5b2c8d1e40' \
  -H "Authorization: Bearer $CLOSEPACT_API_KEY"
Response · 200
{
  "deleted": true
}

Path parameters

  • employeestring(uuid)required

    The employee id.

  • rulestring(uuid)required

    The availability rule id.

Responses

  • Headers

    • X-RateLimit-Limit — Requests this key may make per minute.
    • X-RateLimit-Remaining — Requests left in the current minute.
    • deletedbooleanrequired

      One oftrue

  • 401No key, or the key is invalid, revoked or expired, or its creator no longer has access.
    Errors
  • 402The organization has not bought the module this endpoint belongs to, or it has lapsed to read-only, or its tier does not include what the operation needs: feature names the capability (the operation's x-feature) and required_tier the cheapest tier that grants it. Every operation answers this with "feature": "core.api" when no module the organization holds is on a tier that includes the API.
    Errors
  • 403The key lacks the scope, or the member it acts as lacks the permission or holds no seat in the module (module_seat_required — an administrator assigns seats under Settings → Users), or the organization is suspended.
    Errors
  • 404No such record in this organization.
    Errors
  • 429The key has made more requests this minute than its limit allows.
    Errors

List skills

GET/skills

The organization's competences, by name — the ids to use in skill_ids on employees and services, and in filter[skill_id]. The whole list, not a page. Skills are managed in the panel.

curl 'https://api.closepact.com/v1/api/skills' \
  -H "Authorization: Bearer $CLOSEPACT_API_KEY"
Response · 200
{
  "data": [
    {
      "id": "01a15b70-7c8e-7f00-b1c2-d3e4f5061728",
      "name": "Fönsterputs",
      "slug": "fonsterputs",
      "color": "#56CCF2"
    },
    {
      "id": "01a15b70-7c8d-7e9f-a0b1-c2d3e4f50617",
      "name": "Storstädning",
      "slug": "storstadning",
      "color": "#27AE60"
    }
  ]
}

Responses

  • Headers

    • X-RateLimit-Limit — Requests this key may make per minute.
    • X-RateLimit-Remaining — Requests left in the current minute.
    • dataarray of objectsrequired
      • idstring(uuid)required

        The skill id, for skill_ids on employees and services.

      • namestringrequired

        Name, e.g. "Storstädning".

      • slugstringrequired

        URL-friendly name, unique in the organization.

      • colorstringnullablerequired

        Colour, or null.

  • 401No key, or the key is invalid, revoked or expired, or its creator no longer has access.
    Errors
  • 402The organization has not bought the module this endpoint belongs to, or it has lapsed to read-only, or its tier does not include what the operation needs: feature names the capability (the operation's x-feature) and required_tier the cheapest tier that grants it. Every operation answers this with "feature": "core.api" when no module the organization holds is on a tier that includes the API.
    Errors
  • 403The key lacks the scope, or the member it acts as lacks the permission or holds no seat in the module (module_seat_required — an administrator assigns seats under Settings → Users), or the organization is suspended.
    Errors
  • 429The key has made more requests this minute than its limit allows.
    Errors