Services
The service catalogue (tjänster): price, VAT rate, ROT/RUT eligibility, usual duration and the skills each service requires.
List services
/servicesThe 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"{
"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
qstringSearch in the name (case-insensitive, substring).
Example
städfilter[active]boolean1for only active services,0for only retired ones.filter[skill_id]string(uuid)Only services that require this skill.
limitintegerItems per page, 1–100.
Default
251–100cursorstringOpaque cursor from
meta.next_cursorormeta.prev_cursorof 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 objectsrequiredidstring(uuid)requiredThe service id.
namestringrequiredName, e.g. "Flyttstädning".
descriptionstringnullablerequiredDescription, or null.
default_duration_minintegerrequiredHow long a visit usually takes, in minutes; what the calendar places a job as.
pricingobjectrequiredcolorstringnullablerequiredColour on the board, or null.
is_activebooleanrequiredWhether it can be chosen for new work. Retire a service by setting this to false.
sub_entity_idstring(uuid)nullablerequiredThe office (sub-entity) the service belongs to, or null for all.
skillsarray of objectsrequiredCompetences required to do it. Empty means anybody can.
created_atstring(date-time)requiredISO 8601 date-time, in UTC.
updated_atstring(date-time)requiredISO 8601 date-time, in UTC.
linksobjectrequiredmetaobjectrequired
- 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:Errors
featurenames the capability (the operation'sx-feature) andrequired_tierthe 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. - 403The key lacks the scope, or the member it acts as lacks the permission or holds no seat in the module (Errors
module_seat_required— an administrator assigns seats under Settings → Users), or the organization is suspended. - 429The key has made more requests this minute than its limit allows.Errors
Create a service
/servicesAdds 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"
]
}'{
"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
namestringrequiredName.
at most 160 characters
descriptionstringnullableDescription.
default_duration_minintegerUsual duration in minutes, 5–1440. Default 60.
5–1,440
price_modelstringDefault
hourly.One of
hourlyfixedper_unitunit_price_centsintegerAmount in öre (1 SEK = 100 öre), excluding VAT. Default 0.
≥ 0
unit_labelstringnullableWhat a unit is called.
at most 32 characters
vat_rateintegerVAT in percent — one of the Swedish rates. Default 25.
One of
251260rot_rut_eligiblebooleanWhether the work qualifies for ROT/RUT. Default false.
colorstringnullableColour on the board.
at most 16 characters
is_activebooleanDefault true.
sub_entity_idstring(uuid)nullableThe 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.
dataobjectrequiredSomething the company sells by the visit (tjänst): what the schedule places, the booking widget offers and the invoice prices.
idstring(uuid)requiredThe service id.
namestringrequiredName, e.g. "Flyttstädning".
descriptionstringnullablerequiredDescription, or null.
default_duration_minintegerrequiredHow long a visit usually takes, in minutes; what the calendar places a job as.
pricingobjectrequiredcolorstringnullablerequiredColour on the board, or null.
is_activebooleanrequiredWhether it can be chosen for new work. Retire a service by setting this to false.
sub_entity_idstring(uuid)nullablerequiredThe office (sub-entity) the service belongs to, or null for all.
skillsarray of objectsrequiredCompetences required to do it. Empty means anybody can.
created_atstring(date-time)requiredISO 8601 date-time, in UTC.
updated_atstring(date-time)requiredISO 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:Errors
featurenames the capability (the operation'sx-feature) andrequired_tierthe 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. - 403The key lacks the scope, or the member it acts as lacks the permission or holds no seat in the module (Errors
module_seat_required— an administrator assigns seats under Settings → Users), or the organization is suspended. - 422The request body or query failed validation.Errors
- 429The key has made more requests this minute than its limit allows.Errors
curl 'https://api.closepact.com/v1/api/services/01a14f2c-7c1e-7d0b-9a3e-3f5b2c8d1e40' \
-H "Authorization: Bearer $CLOSEPACT_API_KEY"{
"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)requiredThe service id.
Responses
Headers
X-RateLimit-Limit— Requests this key may make per minute.X-RateLimit-Remaining— Requests left in the current minute.
dataobjectrequiredSomething the company sells by the visit (tjänst): what the schedule places, the booking widget offers and the invoice prices.
idstring(uuid)requiredThe service id.
namestringrequiredName, e.g. "Flyttstädning".
descriptionstringnullablerequiredDescription, or null.
default_duration_minintegerrequiredHow long a visit usually takes, in minutes; what the calendar places a job as.
pricingobjectrequiredcolorstringnullablerequiredColour on the board, or null.
is_activebooleanrequiredWhether it can be chosen for new work. Retire a service by setting this to false.
sub_entity_idstring(uuid)nullablerequiredThe office (sub-entity) the service belongs to, or null for all.
skillsarray of objectsrequiredCompetences required to do it. Empty means anybody can.
created_atstring(date-time)requiredISO 8601 date-time, in UTC.
updated_atstring(date-time)requiredISO 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:Errors
featurenames the capability (the operation'sx-feature) andrequired_tierthe 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. - 403The key lacks the scope, or the member it acts as lacks the permission or holds no seat in the module (Errors
module_seat_required— an administrator assigns seats under Settings → Users), or the organization is suspended. - 404No such record in this organization.Errors
- 429The key has made more requests this minute than its limit allows.Errors
Update a service
/services/{service}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
}'{
"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)requiredThe service id.
Request body
application/json · required
namestringName.
at most 160 characters
descriptionstringnullableDescription.
default_duration_minintegerUsual duration in minutes, 5–1440. Default 60.
5–1,440
price_modelstringDefault
hourly.One of
hourlyfixedper_unitunit_price_centsintegerAmount in öre (1 SEK = 100 öre), excluding VAT. Default 0.
≥ 0
unit_labelstringnullableWhat a unit is called.
at most 32 characters
vat_rateintegerVAT in percent — one of the Swedish rates. Default 25.
One of
251260rot_rut_eligiblebooleanWhether the work qualifies for ROT/RUT. Default false.
colorstringnullableColour on the board.
at most 16 characters
is_activebooleanDefault true.
sub_entity_idstring(uuid)nullableThe 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.
dataobjectrequiredSomething the company sells by the visit (tjänst): what the schedule places, the booking widget offers and the invoice prices.
idstring(uuid)requiredThe service id.
namestringrequiredName, e.g. "Flyttstädning".
descriptionstringnullablerequiredDescription, or null.
default_duration_minintegerrequiredHow long a visit usually takes, in minutes; what the calendar places a job as.
pricingobjectrequiredcolorstringnullablerequiredColour on the board, or null.
is_activebooleanrequiredWhether it can be chosen for new work. Retire a service by setting this to false.
sub_entity_idstring(uuid)nullablerequiredThe office (sub-entity) the service belongs to, or null for all.
skillsarray of objectsrequiredCompetences required to do it. Empty means anybody can.
created_atstring(date-time)requiredISO 8601 date-time, in UTC.
updated_atstring(date-time)requiredISO 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:Errors
featurenames the capability (the operation'sx-feature) andrequired_tierthe 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. - 403The key lacks the scope, or the member it acts as lacks the permission or holds no seat in the module (Errors
module_seat_required— an administrator assigns seats under Settings → Users), or the organization is suspended. - 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
/services/{service}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"{
"deleted": true
}Path parameters
servicestring(uuid)requiredThe service id.
Responses
Headers
X-RateLimit-Limit— Requests this key may make per minute.X-RateLimit-Remaining— Requests left in the current minute.
deletedbooleanrequiredOne of
true
- 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:Errors
featurenames the capability (the operation'sx-feature) andrequired_tierthe 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. - 403The key lacks the scope, or the member it acts as lacks the permission or holds no seat in the module (Errors
module_seat_required— an administrator assigns seats under Settings → Users), or the organization is suspended. - 404No such record in this organization.Errors
- 429The key has made more requests this minute than its limit allows.Errors