Rooms
Deal rooms: the branded page a buyer opens to read your offer, watch videos, download documents and accept a quote. A room is drafted, filled with content, given stakeholders, and published; it stays open to buyers until it expires.
Creating and changing rooms is included in the Pro tier of proposals (proposals.rooms); on a lower tier those operations answer 402 and the rooms already written stay readable.
List rooms
/roomsReturns the organization's rooms as a cursor-paginated list, newest first unless you ask for another order. Rooms in the list carry no contents or stakeholders; fetch a single room for those.
To match several statuses, repeat the filter with brackets: filter[status][]=draft&filter[status][]=published. Page through with cursor until meta.next_cursor is null.
curl 'https://api.closepact.com/v1/api/rooms' \
-H "Authorization: Bearer $CLOSEPACT_API_KEY"{
"data": [
{
"id": "01a15c40-1f2e-7d9a-8b3c-4e5f6a7b8c9d",
"slug": "k7Qm2xTb9pLw",
"title": "Hemstäd för familjen Ny",
"description": "Allt om er städning: offert, avtal och schema.",
"status": "published",
"published_at": "2026-10-13T09:00:00+00:00",
"expires_at": "2026-11-13T09:00:00+00:00",
"require_email": true,
"password_protected": false,
"brand_overrides": null,
"settings": null,
"deal_id": "01a15c2e-4b7a-7f3e-9c1d-2e8f6a0b4c71",
"created_by": {
"id": "01a14eb3-c634-7238-bc76-18b09b287f98",
"name": "Anna Lindqvist",
"email": "anna@nordiskfastighet.se"
},
"created_at": "2026-10-12T08:20:11+00:00",
"updated_at": "2026-10-13T09:00:00+00:00"
}
],
"links": {
"first": null,
"last": null,
"prev": null,
"next": null
},
"meta": {
"path": "https://api.closepact.com/v1/api/rooms",
"per_page": 25,
"next_cursor": null,
"prev_cursor": null
}
}Query parameters
filter[status]stringOnly rooms with this status.
One of
draftpublishedexpiredarchivedfilter[deal_id]string(uuid)Only rooms for this deal.
qstringText the room title contains, case-insensitively.
sortstringOne sort field, optionally prefixed with
-for descending. Unpublished rooms sort as though published at the end of time when sorting bypublished_at.One of
created_at-created_atupdated_at-updated_attitle-titlepublished_at-published_atDefault
-created_atlimitintegerItems per page. Values outside 1–100 are clamped.
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)requiredslugstringrequiredThe unguessable part of the room's public link.
titlestringrequireddescriptionstringnullablerequiredstatusstringrequireddraftuntil published;publishedwhile buyers can open it;expiredonce closed to buyers;archivedwhen put away in the panel.One of
draftpublishedexpiredarchivedpublished_atstring(date-time)nullablerequiredexpires_atstring(date-time)nullablerequiredWhen buyers lose access; null for never.
require_emailbooleanrequiredWhether visitors must give their e-mail before the room opens.
password_protectedbooleanrequiredWhether a password is required. The password itself is never returned.
brand_overridesobject | array of valuesnullablerequiredAn empty set comes back as
[].at most 0 items
settingsobject | array of valuesnullablerequiredAn empty set comes back as
[].at most 0 items
deal_idstring(uuid)nullablerequiredcreated_byobjectThe member who created the room. Left out of the answers to publish (when already published) and expire.
contentsarray of objectsThe room's content blocks in display order. Only on Retrieve a room.
stakeholdersarray of objectsThe room's stakeholders. Only on Retrieve a room.
created_atstring(date-time)requiredupdated_atstring(date-time)required
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 room
/roomsCreates an empty room as a draft, with a fresh unguessable slug and the member the key acts as as its creator. Buyers cannot open it until it is published.
A typical integration creates the room, adds contents and stakeholders, then publishes it. Not idempotent: each call creates another room.
curl -X POST 'https://api.closepact.com/v1/api/rooms' \
-H "Authorization: Bearer $CLOSEPACT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Hemstäd för familjen Ny",
"description": "Allt om er städning: offert, avtal och schema.",
"deal_id": "01a15c2e-4b7a-7f3e-9c1d-2e8f6a0b4c71",
"expires_at": "2026-11-13T09:00:00+00:00"
}'{
"data": {
"id": "01a15c40-1f2e-7d9a-8b3c-4e5f6a7b8c9d",
"slug": "k7Qm2xTb9pLw",
"title": "Hemstäd för familjen Ny",
"description": "Allt om er städning: offert, avtal och schema.",
"status": "draft",
"published_at": null,
"expires_at": "2026-11-13T09:00:00+00:00",
"require_email": true,
"password_protected": false,
"brand_overrides": null,
"settings": null,
"deal_id": "01a15c2e-4b7a-7f3e-9c1d-2e8f6a0b4c71",
"created_by": {
"id": "01a14eb3-c634-7238-bc76-18b09b287f98",
"name": "Anna Lindqvist",
"email": "anna@nordiskfastighet.se"
},
"created_at": "2026-10-12T08:20:11+00:00",
"updated_at": "2026-10-12T08:20:11+00:00"
}
}Request body
application/json · required
titlestringrequired2–255 characters
descriptionstringnullableShown to buyers under the title.
at most 5,000 characters
deal_idstring(uuid)nullableA deal in this organization. Cannot be changed later.
expires_atstring(date-time)nullableWhen buyers lose access. Must be in the future.
require_emailbooleanAsk visitors for their e-mail before showing the room.
Default
truebrand_overridesobjectnullableColours, logo and fonts for this room instead of the organization's brand kit.
settingsobjectnullableDisplay settings used by the room page.
Responses
Headers
X-RateLimit-Limit— Requests this key may make per minute.X-RateLimit-Remaining— Requests left in the current minute.
dataobjectrequiredidstring(uuid)requiredslugstringrequiredThe unguessable part of the room's public link.
titlestringrequireddescriptionstringnullablerequiredstatusstringrequireddraftuntil published;publishedwhile buyers can open it;expiredonce closed to buyers;archivedwhen put away in the panel.One of
draftpublishedexpiredarchivedpublished_atstring(date-time)nullablerequiredexpires_atstring(date-time)nullablerequiredWhen buyers lose access; null for never.
require_emailbooleanrequiredWhether visitors must give their e-mail before the room opens.
password_protectedbooleanrequiredWhether a password is required. The password itself is never returned.
brand_overridesobject | array of valuesnullablerequiredAn empty set comes back as
[].at most 0 items
settingsobject | array of valuesnullablerequiredAn empty set comes back as
[].at most 0 items
deal_idstring(uuid)nullablerequiredcreated_byobjectThe member who created the room. Left out of the answers to publish (when already published) and expire.
contentsarray of objectsThe room's content blocks in display order. Only on Retrieve a room.
stakeholdersarray of objectsThe room's stakeholders. Only on Retrieve a room.
created_atstring(date-time)requiredupdated_atstring(date-time)required
- 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
Retrieve a room
/rooms/{room}Returns one room with its contents (in display order) and its stakeholders.
curl 'https://api.closepact.com/v1/api/rooms/01a14f2c-7c1e-7d0b-9a3e-3f5b2c8d1e40' \
-H "Authorization: Bearer $CLOSEPACT_API_KEY"{
"data": {
"id": "01a15c40-1f2e-7d9a-8b3c-4e5f6a7b8c9d",
"slug": "k7Qm2xTb9pLw",
"title": "Hemstäd för familjen Ny",
"description": "Allt om er städning: offert, avtal och schema.",
"status": "published",
"published_at": "2026-10-13T09:00:00+00:00",
"expires_at": "2026-11-13T09:00:00+00:00",
"require_email": true,
"password_protected": false,
"brand_overrides": null,
"settings": null,
"deal_id": "01a15c2e-4b7a-7f3e-9c1d-2e8f6a0b4c71",
"created_by": {
"id": "01a14eb3-c634-7238-bc76-18b09b287f98",
"name": "Anna Lindqvist",
"email": "anna@nordiskfastighet.se"
},
"contents": [
{
"id": "01a15c44-7a1b-7c2d-9e3f-0a1b2c3d4e5f",
"section": "overview",
"kind": "text",
"title": "Välkommen",
"body": "Här hittar ni allt om er hemstädning varannan vecka.",
"url": null,
"payload": null,
"position": 1,
"content_type": null,
"content_id": null
}
],
"stakeholders": [
{
"id": "01a15c47-2b3c-7d4e-8f5a-6b7c8d9e0f1a",
"email": "henrik.ny@solglantan.se",
"name": "Henrik Ny",
"role": "economic",
"status": "active",
"engagement_score": 34,
"influence_score": 0,
"last_active_at": "2026-10-14T18:22:05+00:00",
"invited_at": "2026-10-13T09:01:30+00:00"
}
],
"created_at": "2026-10-12T08:20:11+00:00",
"updated_at": "2026-10-13T09:00:00+00:00"
}
}Path parameters
roomstring(uuid)requiredThe room's id.
Responses
Headers
X-RateLimit-Limit— Requests this key may make per minute.X-RateLimit-Remaining— Requests left in the current minute.
dataobjectrequiredidstring(uuid)requiredslugstringrequiredThe unguessable part of the room's public link.
titlestringrequireddescriptionstringnullablerequiredstatusstringrequireddraftuntil published;publishedwhile buyers can open it;expiredonce closed to buyers;archivedwhen put away in the panel.One of
draftpublishedexpiredarchivedpublished_atstring(date-time)nullablerequiredexpires_atstring(date-time)nullablerequiredWhen buyers lose access; null for never.
require_emailbooleanrequiredWhether visitors must give their e-mail before the room opens.
password_protectedbooleanrequiredWhether a password is required. The password itself is never returned.
brand_overridesobject | array of valuesnullablerequiredAn empty set comes back as
[].at most 0 items
settingsobject | array of valuesnullablerequiredAn empty set comes back as
[].at most 0 items
deal_idstring(uuid)nullablerequiredcreated_byobjectThe member who created the room. Left out of the answers to publish (when already published) and expire.
contentsarray of objectsThe room's content blocks in display order. Only on Retrieve a room.
stakeholdersarray of objectsThe room's stakeholders. Only on Retrieve a room.
created_atstring(date-time)requiredupdated_atstring(date-time)required
- 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 room
/rooms/{room}Changes the fields you send and leaves the rest alone. Changes are visible to buyers at once if the room is published.
Set password to require it before the room opens, or null to remove it; the password is stored hashed and never returned — password_protected tells you whether one is set. expires_at may be moved, cleared or set in the past here. The status, slug and deal cannot be changed: use Publish a room and Expire a room.
curl -X PATCH 'https://api.closepact.com/v1/api/rooms/01a14f2c-7c1e-7d0b-9a3e-3f5b2c8d1e40' \
-H "Authorization: Bearer $CLOSEPACT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Hemstäd – familjen Ny",
"password": "solglantan2026"
}'{
"data": {
"id": "01a15c40-1f2e-7d9a-8b3c-4e5f6a7b8c9d",
"slug": "k7Qm2xTb9pLw",
"title": "Hemstäd – familjen Ny",
"description": "Allt om er städning: offert, avtal och schema.",
"status": "draft",
"published_at": null,
"expires_at": "2026-11-13T09:00:00+00:00",
"require_email": true,
"password_protected": true,
"brand_overrides": null,
"settings": null,
"deal_id": "01a15c2e-4b7a-7f3e-9c1d-2e8f6a0b4c71",
"created_by": {
"id": "01a14eb3-c634-7238-bc76-18b09b287f98",
"name": "Anna Lindqvist",
"email": "anna@nordiskfastighet.se"
},
"created_at": "2026-10-12T08:20:11+00:00",
"updated_at": "2026-10-12T10:02:40+00:00"
}
}Path parameters
roomstring(uuid)requiredThe room's id.
Request body
application/json · required
titlestring2–255 characters
descriptionstringnullableat most 5,000 characters
expires_atstring(date-time)nullablerequire_emailbooleanbrand_overridesobjectnullablesettingsobjectnullablepasswordstringnullablePassword buyers must enter, or null to remove it.
6–128 characters
Responses
Headers
X-RateLimit-Limit— Requests this key may make per minute.X-RateLimit-Remaining— Requests left in the current minute.
dataobjectrequiredidstring(uuid)requiredslugstringrequiredThe unguessable part of the room's public link.
titlestringrequireddescriptionstringnullablerequiredstatusstringrequireddraftuntil published;publishedwhile buyers can open it;expiredonce closed to buyers;archivedwhen put away in the panel.One of
draftpublishedexpiredarchivedpublished_atstring(date-time)nullablerequiredexpires_atstring(date-time)nullablerequiredWhen buyers lose access; null for never.
require_emailbooleanrequiredWhether visitors must give their e-mail before the room opens.
password_protectedbooleanrequiredWhether a password is required. The password itself is never returned.
brand_overridesobject | array of valuesnullablerequiredAn empty set comes back as
[].at most 0 items
settingsobject | array of valuesnullablerequiredAn empty set comes back as
[].at most 0 items
deal_idstring(uuid)nullablerequiredcreated_byobjectThe member who created the room. Left out of the answers to publish (when already published) and expire.
contentsarray of objectsThe room's content blocks in display order. Only on Retrieve a room.
stakeholdersarray of objectsThe room's stakeholders. Only on Retrieve a room.
created_atstring(date-time)requiredupdated_atstring(date-time)required
- 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 room
/rooms/{room}Deletes the room: it leaves lists and lookups at once, and a later request for it is a 404. Quotes and proposals pointing at it keep their deal_room_id.
To cut buyers off from a published room, expire it before deleting it. No webhook fires.
curl -X DELETE 'https://api.closepact.com/v1/api/rooms/01a14f2c-7c1e-7d0b-9a3e-3f5b2c8d1e40' \
-H "Authorization: Bearer $CLOSEPACT_API_KEY"{
"deleted": true
}Path parameters
roomstring(uuid)requiredThe room's id.
Responses
Confirmation that the record was deleted.
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
Publish a room
/rooms/{room}/publishOpens the room to buyers: status becomes published and published_at is set. Stakeholders' personal links and the room link start working, as long as expires_at is empty or in the future — publishing an expired room does not move its expiry, so clear or extend expires_at with an update first.
Fires the room.published webhook. Idempotent: publishing a published room changes nothing, keeps the original published_at and fires nothing. No request body.
curl -X POST 'https://api.closepact.com/v1/api/rooms/01a14f2c-7c1e-7d0b-9a3e-3f5b2c8d1e40/publish' \
-H "Authorization: Bearer $CLOSEPACT_API_KEY"{
"data": {
"id": "01a15c40-1f2e-7d9a-8b3c-4e5f6a7b8c9d",
"slug": "k7Qm2xTb9pLw",
"title": "Hemstäd för familjen Ny",
"description": "Allt om er städning: offert, avtal och schema.",
"status": "published",
"published_at": "2026-10-13T09:00:00+00:00",
"expires_at": "2026-11-13T09:00:00+00:00",
"require_email": true,
"password_protected": false,
"brand_overrides": null,
"settings": null,
"deal_id": "01a15c2e-4b7a-7f3e-9c1d-2e8f6a0b4c71",
"created_by": {
"id": "01a14eb3-c634-7238-bc76-18b09b287f98",
"name": "Anna Lindqvist",
"email": "anna@nordiskfastighet.se"
},
"created_at": "2026-10-12T08:20:11+00:00",
"updated_at": "2026-10-13T09:00:00+00:00"
}
}Path parameters
roomstring(uuid)requiredThe room's id.
Responses
Headers
X-RateLimit-Limit— Requests this key may make per minute.X-RateLimit-Remaining— Requests left in the current minute.
dataobjectrequiredidstring(uuid)requiredslugstringrequiredThe unguessable part of the room's public link.
titlestringrequireddescriptionstringnullablerequiredstatusstringrequireddraftuntil published;publishedwhile buyers can open it;expiredonce closed to buyers;archivedwhen put away in the panel.One of
draftpublishedexpiredarchivedpublished_atstring(date-time)nullablerequiredexpires_atstring(date-time)nullablerequiredWhen buyers lose access; null for never.
require_emailbooleanrequiredWhether visitors must give their e-mail before the room opens.
password_protectedbooleanrequiredWhether a password is required. The password itself is never returned.
brand_overridesobject | array of valuesnullablerequiredAn empty set comes back as
[].at most 0 items
settingsobject | array of valuesnullablerequiredAn empty set comes back as
[].at most 0 items
deal_idstring(uuid)nullablerequiredcreated_byobjectThe member who created the room. Left out of the answers to publish (when already published) and expire.
contentsarray of objectsThe room's content blocks in display order. Only on Retrieve a room.
stakeholdersarray of objectsThe room's stakeholders. Only on Retrieve a room.
created_atstring(date-time)requiredupdated_atstring(date-time)required
- 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
Expire a room
/rooms/{room}/expireCloses the room to buyers now: status becomes expired and expires_at is set to the current time, so the room link and every stakeholder's personal link stop working at once. The room and everything in it are kept; publish it again (after moving expires_at) to reopen it.
Each call stamps expires_at anew. No webhook fires. No request body.
curl -X POST 'https://api.closepact.com/v1/api/rooms/01a14f2c-7c1e-7d0b-9a3e-3f5b2c8d1e40/expire' \
-H "Authorization: Bearer $CLOSEPACT_API_KEY"{
"data": {
"id": "01a15c40-1f2e-7d9a-8b3c-4e5f6a7b8c9d",
"slug": "k7Qm2xTb9pLw",
"title": "Hemstäd för familjen Ny",
"description": "Allt om er städning: offert, avtal och schema.",
"status": "expired",
"published_at": "2026-10-13T09:00:00+00:00",
"expires_at": "2026-10-20T16:45:00+00:00",
"require_email": true,
"password_protected": false,
"brand_overrides": null,
"settings": null,
"deal_id": "01a15c2e-4b7a-7f3e-9c1d-2e8f6a0b4c71",
"created_at": "2026-10-12T08:20:11+00:00",
"updated_at": "2026-10-20T16:45:00+00:00"
}
}Path parameters
roomstring(uuid)requiredThe room's id.
Responses
Headers
X-RateLimit-Limit— Requests this key may make per minute.X-RateLimit-Remaining— Requests left in the current minute.
dataobjectrequiredidstring(uuid)requiredslugstringrequiredThe unguessable part of the room's public link.
titlestringrequireddescriptionstringnullablerequiredstatusstringrequireddraftuntil published;publishedwhile buyers can open it;expiredonce closed to buyers;archivedwhen put away in the panel.One of
draftpublishedexpiredarchivedpublished_atstring(date-time)nullablerequiredexpires_atstring(date-time)nullablerequiredWhen buyers lose access; null for never.
require_emailbooleanrequiredWhether visitors must give their e-mail before the room opens.
password_protectedbooleanrequiredWhether a password is required. The password itself is never returned.
brand_overridesobject | array of valuesnullablerequiredAn empty set comes back as
[].at most 0 items
settingsobject | array of valuesnullablerequiredAn empty set comes back as
[].at most 0 items
deal_idstring(uuid)nullablerequiredcreated_byobjectThe member who created the room. Left out of the answers to publish (when already published) and expire.
contentsarray of objectsThe room's content blocks in display order. Only on Retrieve a room.
stakeholdersarray of objectsThe room's stakeholders. Only on Retrieve a room.
created_atstring(date-time)requiredupdated_atstring(date-time)required
- 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