Estimates
The Estimates API provides CRUD access to estimates, line-item management, status, tags, clone, publish, email and convert-to-invoice.New to the API? Start with Getting started (base URL, response envelope, errors, pagination) and Authentication (API keys).
Identifier note: estimates are addressed by their numeric bill_estimateid.
Totals are computed server-side. You never send totals. You set the line items (and, for summary mode, the tax rates) and the header discount/adjustment; the API computes the subtotal, discount, tax and final amounts to match the CRM exactly.
Scope: file attachments and bulk actions are out of API scope.
The estimate object
| Field | Type | Notes |
|---|---|---|
id | integer | Estimate id. |
status | string | draft, new, accepted, declined, revised, expired. |
client / project_id / category | object/int | Links. |
dates | object | date, expiry_date, created. |
tax_type | string | summary or inline. |
totals | object | All amounts — read-only, computed by the server. |
converted | object | is_converted and the resulting invoice_id (once converted). |
line_items | array | The line items. |
taxes | array | Tax rate records (summary: lineitem_id null; inline: per line). |
tags | array | Tag titles. |
List / search estimates
status, client_id, project_id, category_id, search, sort
(bill_date,bill_expiry_date,bill_final_amount,bill_created), order, limit, page.
Get an estimate
Create an estimate
| Parameter | Type | Required | Notes |
|---|---|---|---|
bill_clientid | integer | yes | Existing client. |
bill_categoryid | integer | yes | Existing category. |
bill_date | date | yes | |
bill_expiry_date | date | no | Optional. |
bill_projectid | integer | no | |
bill_tax_type | string | no | summary (default) or inline. |
bill_notes / bill_terms | string | no |
201, status draft).
Update an estimate (header) + recalculate
| Parameter | Type | Notes |
|---|---|---|
bill_categoryid | integer | required |
bill_date | date | required |
bill_expiry_date | date | optional |
bill_projectid | integer | optional |
bill_notes / bill_terms | string | optional |
bill_tax_type | string | summary/inline |
bill_discount_type | string | none/fixed/percentage |
bill_discount_percentage | numeric | for percentage discounts |
bill_discount_amount | numeric | for fixed discounts |
bill_adjustment_description | string | |
bill_adjustment_amount | numeric | may be negative |
Set line items + recalculate
tax_type:
- summary — pass estimate-level
tax_rate_ids[]; the tax applies to the whole estimate. - inline — give each item its own
tax_rate_id(and optional per-linediscount_type/discount_value).
| Parameter | Type | Required | Notes |
|---|---|---|---|
items[] | array | yes | The full set of line items (replaces existing). |
items[].description | string | yes | |
items[].quantity | numeric | yes | |
items[].rate | numeric | yes | |
items[].unit | string | no | |
items[].long_description | string | no | |
items[].tax_rate_id | integer | no | Inline mode: a tax rate id for the line. |
items[].discount_type / items[].discount_value | string/numeric | no | Inline mode: per-line discount. |
tax_rate_ids[] | array of ints | no | Summary mode: estimate-level tax rate ids. |
totals (200).
Delete an estimate
Change status
| Parameter | Type | Notes |
|---|---|---|
status | string | One of draft, new, accepted, declined, revised. |
Set tags
Clone
| Parameter | Type | Required |
|---|---|---|
bill_clientid | integer | yes |
bill_categoryid | integer | yes |
bill_date | date | yes |
bill_expiry_date | date | no |
bill_projectid | integer | no |
201, status draft).
Publish
409 if already published.
Email the client
409 otherwise). No body.
Convert to invoice
201) — see Invoices.
Errors
See Getting started. Estimate-specific:| Status | Meaning |
|---|---|
404 Not Found | The estimate id does not exist. |
409 Conflict | Already published, or emailing a draft. |
422 Unprocessable Entity | Validation failed (e.g. missing client/category/date, invalid status/tax rate). |