Proposals
Written proposals, edited in the panel's editor as a tree of blocks (headings, paragraphs, lists, images, pricing tables…). Every edit of the content is kept as a numbered version.
List proposals
/proposalsReturns the organization's proposals, most recently changed first, with their full content, as a cursor-paginated list. Page through with cursor until meta.next_cursor is null; links.next keeps your filters.
curl 'https://api.closepact.com/v1/api/proposals' \
-H "Authorization: Bearer $CLOSEPACT_API_KEY"{
"data": [
{
"id": "01a15c60-4e5f-7a6b-8c7d-9e0f1a2b3c4d",
"title": "Förslag hemstädning",
"status": "published",
"current_version": 3,
"deal_id": "01a15c2e-4b7a-7f3e-9c1d-2e8f6a0b4c71",
"deal_room_id": "01a15c40-1f2e-7d9a-8b3c-4e5f6a7b8c9d",
"blocks": [
{
"type": "heading",
"attrs": {
"level": 1
},
"content": [
{
"type": "text",
"text": "Hemstäd för familjen Ny"
}
]
},
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Varannan vecka, två timmar per tillfälle."
}
]
}
],
"settings": [],
"published_at": "2026-10-14T07:30:00+00:00",
"created_at": "2026-10-12T09:00:00+00:00",
"updated_at": "2026-10-14T07:30:00+00:00"
}
],
"links": {
"first": null,
"last": null,
"prev": null,
"next": null
},
"meta": {
"path": "https://api.closepact.com/v1/api/proposals",
"per_page": 25,
"next_cursor": null,
"prev_cursor": null
}
}Query parameters
deal_idstring(uuid)Only proposals for this deal.
deal_room_idstring(uuid)Only proposals for this room.
limitintegerItems 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)requiredtitlestringrequiredstatusstringrequireddraftwhile being written;in_reviewwhen held for approval in the panel;publishedonce released.One of
draftin_reviewpublishedcurrent_versionintegerrequiredGoes up by one with every content change.
≥ 1
deal_idstring(uuid)nullablerequireddeal_room_idstring(uuid)nullablerequiredblocksarray of objectsrequiredsettingsobject | array of valuesnullablerequiredEditor display settings. An empty set comes back as
[].at most 0 items
published_atstring(date-time)nullablerequiredcreated_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 proposal
/proposalsCreates a draft proposal, optionally with content, and saves it as version 1 ("Initial draft") under the member the key acts as.
Blocks are checked before anything is saved: an unknown block type anywhere in the tree is a 422. Keys a block does not support are dropped, and text longer than 10 000 characters is cut. Not idempotent: each call creates another proposal.
curl -X POST 'https://api.closepact.com/v1/api/proposals' \
-H "Authorization: Bearer $CLOSEPACT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Förslag hemstädning",
"deal_id": "01a15c2e-4b7a-7f3e-9c1d-2e8f6a0b4c71",
"blocks": [
{
"type": "heading",
"attrs": {
"level": 1
},
"content": [
{
"type": "text",
"text": "Hemstäd för familjen Ny"
}
]
},
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Varannan vecka, två timmar per tillfälle."
}
]
}
]
}'{
"data": {
"id": "01a15c60-4e5f-7a6b-8c7d-9e0f1a2b3c4d",
"title": "Förslag hemstädning",
"status": "draft",
"current_version": 1,
"deal_id": "01a15c2e-4b7a-7f3e-9c1d-2e8f6a0b4c71",
"deal_room_id": null,
"blocks": [
{
"type": "heading",
"attrs": {
"level": 1
},
"content": [
{
"type": "text",
"text": "Hemstäd för familjen Ny"
}
]
},
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Varannan vecka, två timmar per tillfälle."
}
]
}
],
"settings": [],
"published_at": null,
"created_at": "2026-10-12T09:00:00+00:00",
"updated_at": "2026-10-12T09:00:00+00:00"
}
}Request body
application/json · required
titlestringrequiredat most 255 characters
deal_idstring(uuid)nullableA deal in this organization.
deal_room_idstring(uuid)nullableA room in this organization.
blocksarray of objectsnullableThe content. Leave out for an empty proposal.
settingsobjectnullableDisplay settings used by the editor.
Responses
Headers
X-RateLimit-Limit— Requests this key may make per minute.X-RateLimit-Remaining— Requests left in the current minute.
dataobjectrequiredidstring(uuid)requiredtitlestringrequiredstatusstringrequireddraftwhile being written;in_reviewwhen held for approval in the panel;publishedonce released.One of
draftin_reviewpublishedcurrent_versionintegerrequiredGoes up by one with every content change.
≥ 1
deal_idstring(uuid)nullablerequireddeal_room_idstring(uuid)nullablerequiredblocksarray of objectsrequiredsettingsobject | array of valuesnullablerequiredEditor display settings. An empty set comes back as
[].at most 0 items
published_atstring(date-time)nullablerequiredcreated_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
curl 'https://api.closepact.com/v1/api/proposals/01a14f2c-7c1e-7d0b-9a3e-3f5b2c8d1e40' \
-H "Authorization: Bearer $CLOSEPACT_API_KEY"{
"data": {
"id": "01a15c60-4e5f-7a6b-8c7d-9e0f1a2b3c4d",
"title": "Förslag hemstädning",
"status": "draft",
"current_version": 2,
"deal_id": "01a15c2e-4b7a-7f3e-9c1d-2e8f6a0b4c71",
"deal_room_id": null,
"blocks": [
{
"type": "heading",
"attrs": {
"level": 1
},
"content": [
{
"type": "text",
"text": "Hemstäd för familjen Ny"
}
]
},
{
"type": "bulletList",
"content": [
{
"type": "listItem",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Dammsugning och våttorkning av golv"
}
]
}
]
},
{
"type": "listItem",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Rengöring av kök och badrum"
}
]
}
]
}
]
}
],
"settings": [],
"published_at": null,
"created_at": "2026-10-12T09:00:00+00:00",
"updated_at": "2026-10-12T10:15:00+00:00"
}
}Path parameters
proposalstring(uuid)requiredThe proposal'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)requiredtitlestringrequiredstatusstringrequireddraftwhile being written;in_reviewwhen held for approval in the panel;publishedonce released.One of
draftin_reviewpublishedcurrent_versionintegerrequiredGoes up by one with every content change.
≥ 1
deal_idstring(uuid)nullablerequireddeal_room_idstring(uuid)nullablerequiredblocksarray of objectsrequiredsettingsobject | array of valuesnullablerequiredEditor display settings. An empty set comes back as
[].at most 0 items
published_atstring(date-time)nullablerequiredcreated_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
Replace a proposal's content
/proposals/{proposal}Replaces the whole block tree — send the complete content, not a change — and saves it as a new version: current_version goes up by one and a snapshot is kept with your notes, under the member the key acts as. The title is not changed here; see Rename a proposal.
The same block checks as on create apply; nothing is saved when one fails. A published proposal can be edited too, and stays published.
curl -X PATCH 'https://api.closepact.com/v1/api/proposals/01a14f2c-7c1e-7d0b-9a3e-3f5b2c8d1e40' \
-H "Authorization: Bearer $CLOSEPACT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"blocks": [
{
"type": "heading",
"attrs": {
"level": 1
},
"content": [
{
"type": "text",
"text": "Hemstäd för familjen Ny"
}
]
},
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Nu med fönsterputs två gånger per år."
}
]
}
],
"notes": "La till fönsterputs"
}'{
"data": {
"id": "01a15c60-4e5f-7a6b-8c7d-9e0f1a2b3c4d",
"title": "Förslag hemstädning",
"status": "draft",
"current_version": 2,
"deal_id": "01a15c2e-4b7a-7f3e-9c1d-2e8f6a0b4c71",
"deal_room_id": null,
"blocks": [
{
"type": "heading",
"attrs": {
"level": 1
},
"content": [
{
"type": "text",
"text": "Hemstäd för familjen Ny"
}
]
},
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Nu med fönsterputs två gånger per år."
}
]
}
],
"settings": [],
"published_at": null,
"created_at": "2026-10-12T09:00:00+00:00",
"updated_at": "2026-10-12T10:15:00+00:00"
}
}Path parameters
proposalstring(uuid)requiredThe proposal's id.
Request body
application/json · required
blocksarray of objectsrequiredat least 1 item
notesstringnullableWhat changed, kept with the version.
at most 255 characters
Responses
Headers
X-RateLimit-Limit— Requests this key may make per minute.X-RateLimit-Remaining— Requests left in the current minute.
dataobjectrequiredidstring(uuid)requiredtitlestringrequiredstatusstringrequireddraftwhile being written;in_reviewwhen held for approval in the panel;publishedonce released.One of
draftin_reviewpublishedcurrent_versionintegerrequiredGoes up by one with every content change.
≥ 1
deal_idstring(uuid)nullablerequireddeal_room_idstring(uuid)nullablerequiredblocksarray of objectsrequiredsettingsobject | array of valuesnullablerequiredEditor display settings. An empty set comes back as
[].at most 0 items
published_atstring(date-time)nullablerequiredcreated_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 proposal
/proposals/{proposal}Deletes the proposal: it leaves lists and lookups at once and a later request for it is a 404. No webhook fires.
curl -X DELETE 'https://api.closepact.com/v1/api/proposals/01a14f2c-7c1e-7d0b-9a3e-3f5b2c8d1e40' \
-H "Authorization: Bearer $CLOSEPACT_API_KEY"204 — no response bodyPath parameters
proposalstring(uuid)requiredThe proposal's id.
Responses
- 204The proposal was deleted. No body.
- 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
Rename a proposal
/proposals/{proposal}/renameChanges the title. The content and version are not touched, and no new version is saved.
curl -X PATCH 'https://api.closepact.com/v1/api/proposals/01a14f2c-7c1e-7d0b-9a3e-3f5b2c8d1e40/rename' \
-H "Authorization: Bearer $CLOSEPACT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Förslag hemstäd 2027"
}'{
"data": {
"id": "01a15c60-4e5f-7a6b-8c7d-9e0f1a2b3c4d",
"title": "Förslag hemstäd 2027",
"status": "draft",
"current_version": 2,
"deal_id": "01a15c2e-4b7a-7f3e-9c1d-2e8f6a0b4c71",
"deal_room_id": null,
"blocks": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Nu med fönsterputs två gånger per år."
}
]
}
],
"settings": [],
"published_at": null,
"created_at": "2026-10-12T09:00:00+00:00",
"updated_at": "2026-10-12T10:20:00+00:00"
}
}Path parameters
proposalstring(uuid)requiredThe proposal's id.
Request body
application/json · required
titlestringrequired1–255 characters
Responses
Headers
X-RateLimit-Limit— Requests this key may make per minute.X-RateLimit-Remaining— Requests left in the current minute.
dataobjectrequiredidstring(uuid)requiredtitlestringrequiredstatusstringrequireddraftwhile being written;in_reviewwhen held for approval in the panel;publishedonce released.One of
draftin_reviewpublishedcurrent_versionintegerrequiredGoes up by one with every content change.
≥ 1
deal_idstring(uuid)nullablerequireddeal_room_idstring(uuid)nullablerequiredblocksarray of objectsrequiredsettingsobject | array of valuesnullablerequiredEditor display settings. An empty set comes back as
[].at most 0 items
published_atstring(date-time)nullablerequiredcreated_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
Publish a proposal
/proposals/{proposal}/publishMarks the proposal published and sets published_at to now; calling it again moves published_at to the new now. Nobody is e-mailed and no webhook fires — to put a proposal in front of a buyer, add it to a room as a proposal content block. No request body.
curl -X POST 'https://api.closepact.com/v1/api/proposals/01a14f2c-7c1e-7d0b-9a3e-3f5b2c8d1e40/publish' \
-H "Authorization: Bearer $CLOSEPACT_API_KEY"{
"data": {
"id": "01a15c60-4e5f-7a6b-8c7d-9e0f1a2b3c4d",
"title": "Förslag hemstäd 2027",
"status": "published",
"current_version": 2,
"deal_id": "01a15c2e-4b7a-7f3e-9c1d-2e8f6a0b4c71",
"deal_room_id": null,
"blocks": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Nu med fönsterputs två gånger per år."
}
]
}
],
"settings": [],
"published_at": "2026-10-14T07:30:00+00:00",
"created_at": "2026-10-12T09:00:00+00:00",
"updated_at": "2026-10-14T07:30:00+00:00"
}
}Path parameters
proposalstring(uuid)requiredThe proposal'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)requiredtitlestringrequiredstatusstringrequireddraftwhile being written;in_reviewwhen held for approval in the panel;publishedonce released.One of
draftin_reviewpublishedcurrent_versionintegerrequiredGoes up by one with every content change.
≥ 1
deal_idstring(uuid)nullablerequireddeal_room_idstring(uuid)nullablerequiredblocksarray of objectsrequiredsettingsobject | array of valuesnullablerequiredEditor display settings. An empty set comes back as
[].at most 0 items
published_atstring(date-time)nullablerequiredcreated_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