Services

The service catalogue (tjänster): price, VAT rate, ROT/RUT eligibility, usual duration and the skills each service requires.

List services

GET/services

The service catalogue by name, active and retired. Cursor-paginated: follow links.next, or pass meta.next_cursor as cursor.

curl 'https://api.closepact.com/v1/api/services' \
  -H "Authorization: Bearer $CLOSEPACT_API_KEY"
Response · 200
{
  "data": [
    {
      "id": "01a15b80-5a6b-7c8d-9eaf-b0c1d2e3f405",
      "name": "Flyttstädning",
      "description": "Städning enligt branschens checklista, inklusive ugn, kyl och fönster.",
      "default_duration_min": 240,
      "pricing": {
        "model": "hourly",
        "unit_price_cents": 49500,
        "unit_label": "timme",
        "vat_rate": 25,
        "rot_rut_eligible": true
      },
      "color": "#9B51E0",
      "is_active": true,
      "sub_entity_id": null,
      "skills": [
        {
          "id": "01a15b70-7c8d-7e9f-a0b1-c2d3e4f50617",
          "name": "Storstädning",
          "color": "#27AE60"
        }
      ],
      "created_at": "2025-11-04T09:00:00+00:00",
      "updated_at": "2026-08-12T14:20:00+00:00"
    }
  ],
  "links": {
    "first": null,
    "last": null,
    "prev": null,
    "next": null
  },
  "meta": {
    "path": "https://api.closepact.com/v1/api/services",
    "per_page": 25,
    "next_cursor": null,
    "prev_cursor": null
  }
}

Query parameters

  • qstring

    Search in the name (case-insensitive, substring).

    Example städ

  • filter[active]boolean

    1 for only active services, 0 for only retired ones.

  • filter[skill_id]string(uuid)

    Only services that require 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 service id.

      • namestringrequired

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

      • descriptionstringnullablerequired

        Description, or null.

      • default_duration_minintegerrequired

        How long a visit usually takes, in minutes; what the calendar places a job as.

      • pricingobjectrequired
      • colorstringnullablerequired

        Colour on the board, or null.

      • is_activebooleanrequired

        Whether it can be chosen for new work. Retire a service by setting this to false.

      • sub_entity_idstring(uuid)nullablerequired

        The office (sub-entity) the service belongs to, or null for all.

      • skillsarray of objectsrequired

        Competences required to do it. Empty means anybody can.

      • 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 a service

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

Adds a service to the catalogue. Each service carries its own VAT rate, because a cleaning is 25 % and a passenger transport 6 %.

curl -X POST 'https://api.closepact.com/v1/api/services' \
  -H "Authorization: Bearer $CLOSEPACT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Flyttstädning",
  "description": "Städning enligt branschens checklista, inklusive ugn, kyl och fönster.",
  "default_duration_min": 240,
  "price_model": "hourly",
  "unit_price_cents": 49500,
  "unit_label": "timme",
  "vat_rate": 25,
  "rot_rut_eligible": true,
  "skill_ids": [
    "01a15b70-7c8d-7e9f-a0b1-c2d3e4f50617"
  ]
}'
Response · 201
{
  "data": {
    "id": "01a15b80-5a6b-7c8d-9eaf-b0c1d2e3f405",
    "name": "Flyttstädning",
    "description": "Städning enligt branschens checklista, inklusive ugn, kyl och fönster.",
    "default_duration_min": 240,
    "pricing": {
      "model": "hourly",
      "unit_price_cents": 49500,
      "unit_label": "timme",
      "vat_rate": 25,
      "rot_rut_eligible": true
    },
    "color": "#9B51E0",
    "is_active": true,
    "sub_entity_id": null,
    "skills": [
      {
        "id": "01a15b70-7c8d-7e9f-a0b1-c2d3e4f50617",
        "name": "Storstädning",
        "color": "#27AE60"
      }
    ],
    "created_at": "2025-11-04T09:00:00+00:00",
    "updated_at": "2026-08-12T14:20:00+00:00"
  }
}

Request body

application/json · required

  • namestringrequired

    Name.

    at most 160 characters

  • descriptionstringnullable

    Description.

  • default_duration_mininteger

    Usual duration in minutes, 5–1440. Default 60.

    5–1,440

  • price_modelstring

    Default hourly.

    One ofhourlyfixedper_unit

  • unit_price_centsinteger

    Amount in öre (1 SEK = 100 öre), excluding VAT. Default 0.

    ≥ 0

  • unit_labelstringnullable

    What a unit is called.

    at most 32 characters

  • vat_rateinteger

    VAT in percent — one of the Swedish rates. Default 25.

    One of251260

  • rot_rut_eligibleboolean

    Whether the work qualifies for ROT/RUT. Default false.

  • colorstringnullable

    Colour on the board.

    at most 16 characters

  • is_activeboolean

    Default true.

  • sub_entity_idstring(uuid)nullable

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

  • skill_idsarray of strings(uuid)

    Replaces the required skills with these (see GET /skills). Ids that are not your organization's are ignored. Leave out to keep the current ones.

Responses

  • Headers

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

      Something the company sells by the visit (tjänst): what the schedule places, the booking widget offers and the invoice prices.

      • idstring(uuid)required

        The service id.

      • namestringrequired

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

      • descriptionstringnullablerequired

        Description, or null.

      • default_duration_minintegerrequired

        How long a visit usually takes, in minutes; what the calendar places a job as.

      • pricingobjectrequired
      • colorstringnullablerequired

        Colour on the board, or null.

      • is_activebooleanrequired

        Whether it can be chosen for new work. Retire a service by setting this to false.

      • sub_entity_idstring(uuid)nullablerequired

        The office (sub-entity) the service belongs to, or null for all.

      • skillsarray of objectsrequired

        Competences required to do it. Empty means anybody can.

      • 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 a service

GET/services/{service}

One service with its required skills.

curl 'https://api.closepact.com/v1/api/services/01a14f2c-7c1e-7d0b-9a3e-3f5b2c8d1e40' \
  -H "Authorization: Bearer $CLOSEPACT_API_KEY"
Response · 200
{
  "data": {
    "id": "01a15b80-5a6b-7c8d-9eaf-b0c1d2e3f405",
    "name": "Flyttstädning",
    "description": "Städning enligt branschens checklista, inklusive ugn, kyl och fönster.",
    "default_duration_min": 240,
    "pricing": {
      "model": "hourly",
      "unit_price_cents": 49500,
      "unit_label": "timme",
      "vat_rate": 25,
      "rot_rut_eligible": true
    },
    "color": "#9B51E0",
    "is_active": true,
    "sub_entity_id": null,
    "skills": [
      {
        "id": "01a15b70-7c8d-7e9f-a0b1-c2d3e4f50617",
        "name": "Storstädning",
        "color": "#27AE60"
      }
    ],
    "created_at": "2025-11-04T09:00:00+00:00",
    "updated_at": "2026-08-12T14:20:00+00:00"
  }
}

Path parameters

  • servicestring(uuid)required

    The service id.

Responses

  • Headers

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

      Something the company sells by the visit (tjänst): what the schedule places, the booking widget offers and the invoice prices.

      • idstring(uuid)required

        The service id.

      • namestringrequired

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

      • descriptionstringnullablerequired

        Description, or null.

      • default_duration_minintegerrequired

        How long a visit usually takes, in minutes; what the calendar places a job as.

      • pricingobjectrequired
      • colorstringnullablerequired

        Colour on the board, or null.

      • is_activebooleanrequired

        Whether it can be chosen for new work. Retire a service by setting this to false.

      • sub_entity_idstring(uuid)nullablerequired

        The office (sub-entity) the service belongs to, or null for all.

      • skillsarray of objectsrequired

        Competences required to do it. Empty means anybody can.

      • 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 a service

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

Changes the fields you send. Prices already ordered on work orders do not change: they were copied when ordered.

curl -X PATCH 'https://api.closepact.com/v1/api/services/01a14f2c-7c1e-7d0b-9a3e-3f5b2c8d1e40' \
  -H "Authorization: Bearer $CLOSEPACT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "unit_price_cents": 52500
}'
Response · 200
{
  "data": {
    "id": "01a15b80-5a6b-7c8d-9eaf-b0c1d2e3f405",
    "name": "Flyttstädning",
    "description": "Städning enligt branschens checklista, inklusive ugn, kyl och fönster.",
    "default_duration_min": 240,
    "pricing": {
      "model": "hourly",
      "unit_price_cents": 52500,
      "unit_label": "timme",
      "vat_rate": 25,
      "rot_rut_eligible": true
    },
    "color": "#9B51E0",
    "is_active": true,
    "sub_entity_id": null,
    "skills": [
      {
        "id": "01a15b70-7c8d-7e9f-a0b1-c2d3e4f50617",
        "name": "Storstädning",
        "color": "#27AE60"
      }
    ],
    "created_at": "2025-11-04T09:00:00+00:00",
    "updated_at": "2026-08-12T14:20:00+00:00"
  }
}

Path parameters

  • servicestring(uuid)required

    The service id.

Request body

application/json · required

  • namestring

    Name.

    at most 160 characters

  • descriptionstringnullable

    Description.

  • default_duration_mininteger

    Usual duration in minutes, 5–1440. Default 60.

    5–1,440

  • price_modelstring

    Default hourly.

    One ofhourlyfixedper_unit

  • unit_price_centsinteger

    Amount in öre (1 SEK = 100 öre), excluding VAT. Default 0.

    ≥ 0

  • unit_labelstringnullable

    What a unit is called.

    at most 32 characters

  • vat_rateinteger

    VAT in percent — one of the Swedish rates. Default 25.

    One of251260

  • rot_rut_eligibleboolean

    Whether the work qualifies for ROT/RUT. Default false.

  • colorstringnullable

    Colour on the board.

    at most 16 characters

  • is_activeboolean

    Default true.

  • sub_entity_idstring(uuid)nullable

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

  • skill_idsarray of strings(uuid)

    Replaces the required skills with these (see GET /skills). Ids that are not your organization's are ignored. Leave out to keep the current ones.

Responses

  • Headers

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

      Something the company sells by the visit (tjänst): what the schedule places, the booking widget offers and the invoice prices.

      • idstring(uuid)required

        The service id.

      • namestringrequired

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

      • descriptionstringnullablerequired

        Description, or null.

      • default_duration_minintegerrequired

        How long a visit usually takes, in minutes; what the calendar places a job as.

      • pricingobjectrequired
      • colorstringnullablerequired

        Colour on the board, or null.

      • is_activebooleanrequired

        Whether it can be chosen for new work. Retire a service by setting this to false.

      • sub_entity_idstring(uuid)nullablerequired

        The office (sub-entity) the service belongs to, or null for all.

      • skillsarray of objectsrequired

        Competences required to do it. Empty means anybody can.

      • 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 a service

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

Removes the service from the catalogue. Work orders that ordered it keep their lines. To stop offering a service but keep it visible, set is_active to false instead.

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

Path parameters

  • servicestring(uuid)required

    The service 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