Proposals
The Proposals API provides CRUD access to proposals (documents sent to a client or a lead), plus ancillary actions for status, tags and cloning.New to the API? Start with Getting started (base URL, response envelope, errors, pagination) and Authentication (API keys). Those conventions apply to every endpoint below and are not repeated here.
Identifier note: proposals are addressed by their numericdoc_id. Wherever{id}appears below it is thedoc_id.
Scope: the signature accept flow, publishing & emailing, automation, estimate generation and the rich document editor are managed in-app and are not part of this API. Client accept details are exposed read-only; a proposal can still be marked declined/accepted via the status action.
The proposal object
A proposal belongs to a client or a lead — the unused side isnull.
| Field | Type | Notes |
|---|---|---|
id | integer | Proposal id. Used in all URLs. |
title | string | Proposal title. |
status | string | draft, new, accepted, declined, revised. |
body | string|null | Proposal body (HTML). |
client | object | { id, name } (null when the proposal is for a lead). |
lead | object | { id, name } (null when the proposal is for a client). |
category | object | { id, name }. |
project_id | integer|null | Attached project id (managed in-app). |
dates | object | start, end, created, published. |
signed | object | Read-only client accept details: date, first_name, last_name. |
tags | array | Tag titles. |
List / search proposals
Query parameters
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status. |
client_id | integer | Filter by client id. |
lead_id | integer | Filter by lead id. |
category_id | integer | Filter by category id. |
search | string | Free-text search on the title. |
sort | string | doc_title, doc_status, doc_date_start, doc_created. |
order | string | asc or desc (default desc). |
limit | integer | Results per page (max 100). |
page | integer | Page number. |
Example request
Example response — 200 OK
Get a proposal
200) with message “Proposal retrieved successfully.”
Create a proposal
customer_type). Provide doc_body to set
the content directly, or proposal_template to seed the body from a template. Creates a backing
estimate record.
Body parameters
| Parameter | Type | Required | Notes |
|---|---|---|---|
customer_type | string | yes | client or lead. |
doc_client_id | integer | required if customer_type=client | Existing client id. |
doc_lead_id | integer | required if customer_type=lead | Existing lead id. |
doc_title | string | yes | |
doc_date_start | date | yes | YYYY-MM-DD. |
doc_categoryid | integer | yes | Existing (proposal) category id. |
doc_date_end | date | no | Must be on/after the start date. |
doc_body | string (HTML) | no | Proposal content. Overrides proposal_template. |
proposal_template | integer | no | Template id used to seed the body when doc_body is omitted. |
Example request
Example response — 201 Created
Update a proposal
| Parameter | Type | Required | Notes |
|---|---|---|---|
doc_title | string | yes | |
doc_date_start | date | yes | |
doc_categoryid | integer | yes | Existing category id. |
doc_date_end | date | no | Must be on/after the start date. |
doc_body | string (HTML) | no | Replaces the proposal content. |
200) with message “Proposal updated successfully.”
Delete a proposal
Example response — 200 OK
Change status
| Parameter | Type | Required | Notes |
|---|---|---|---|
status | string | yes | accepted, declined, revised, draft, new. |
200) with message “Proposal status updated successfully.”
Set tags
tags array is the full set — it replaces existing tags; an empty array clears them.
| Parameter | Type | Required | Notes |
|---|---|---|---|
tags | array of strings | yes | Tag titles. Empty array clears all. |
200) with message “Proposal tags updated successfully.”
Clone a proposal
| Parameter | Type | Required | Notes |
|---|---|---|---|
doc_title | string | yes | Title of the new proposal. |
customer_type | string | yes | client or lead. |
doc_client_id | integer | required if customer_type=client | |
doc_lead_id | integer | required if customer_type=lead | |
doc_categoryid | integer | yes | |
doc_date_start | date | yes | |
doc_date_end | date | no |
201) with message “Proposal cloned successfully.”
Errors
See Getting started for the shared error format. Proposal-specific:| Status | Meaning |
|---|---|
404 Not Found | The proposal id does not exist. |
422 Unprocessable Entity | Validation failed (e.g. missing customer/title/date/category, or an invalid status). |