Skip to content

Estimates

Quotes before the work, converted into an invoice once the client accepts.

estimates

List

GET/v1/estimates

List estimates, newest first. A discarded draft is left out unless discarded=true.

Scope
estimates:read
Effect
Read only
MCP tool
list_estimates
Retries
Safe to repeat

Parameters

List parameters
NameInTypeNotes
limitoptionalqueryintegermin 1 · max 50
cursoroptionalquerystringup to 256 chars
statusoptionalqueryenumOne of draft, sent, viewed, accepted, declined, expired, converted, void
clientIdoptionalqueryid—
discardedoptionalqueryboolean—

Returns

data: Estimate[]. Pass meta.cursor back as cursor for the next page.

Example requestSample
curl -X GET "https://api.billingmart.com/v1/estimates" \
  -H "Authorization: Bearer $BILLINGMART_API_KEY"

estimates

Create

POST/v1/estimates

Create a draft estimate.

Scope
estimates:write
Effect
Writes a draft or record
MCP tool
create_estimate
Retries
Send an Idempotency-Key; a repeat replays the stored answer for 24 hours

Request body

JSON. Money is an integer count of minor units beside its currency; quantities are thousandths.

Create request body
FieldTypeNotes
businessIdrequiredid—
clientIdrequiredid—
currencyoptionalCurrency—
languageoptionalstringup to 8 chars
lineItems[]optionalobject[]up to 200 items
lineItems[].idoptionalid—
lineItems[].descriptionoptionalstringWhat the line is for. Optional with a presetKey (the item’s name is used). — up to 2000 chars
lineItems[].quantityMillioptionalintegerQuantity in thousandths: 1000 is one unit, 1500 is 1.5 hours. Defaults to 1000.
lineItems[].rateBasisoptionalenumHow the price applies: fixed for one flat charge, hourly, daily, perUnit, percentage… Optional with a presetKey. — One of fixed, hourly, daily, weekly, monthly, perUnit, perMile, perKilometre, percentage
lineItems[].unitPriceoptionalobjectPrice per unit in integer minor units of the document currency ($5,000.00 is 500000).
lineItems[].unitPrice.minorUnitsrequiredinteger—
lineItems[].unitPrice.currencyrequiredCurrency—
lineItems[].rateBasisPointsoptionalinteger—
lineItems[].taxTreatmentoptionalstring—
lineItems[].taxRateBasisPointsoptionalinteger—
lineItems[].discountBasisPointsoptionalinteger—
lineItems[].presetKeyoptionalstringThe key of one of the business’s products and services (get_business_context lists them); the server fills what the line leaves out. — up to 64 chars
notesoptionalstringup to 4000 chars
issueDateoptionalstringmatches ^\d{4}-\d{2}-\d{2}$
validUntiloptionalstringmatches ^\d{4}-\d{2}-\d{2}$

Returns

data: object

Example requestSample
curl -X POST "https://api.billingmart.com/v1/estimates" \
  -H "Authorization: Bearer $BILLINGMART_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"businessId":"<businessId>","clientId":"<clientId>"}'

estimates

Get

GET/v1/estimates/{estimateId}

One estimate.

Scope
estimates:read
Effect
Read only
MCP tool
get_estimate
Retries
Safe to repeat

Parameters

Get parameters
NameInTypeNotes
estimateIdrequiredpathid—

Returns

data: Estimate

Example requestSample
curl -X GET "https://api.billingmart.com/v1/estimates/{estimateId}" \
  -H "Authorization: Bearer $BILLINGMART_API_KEY"

estimates

Update

PATCH/v1/estimates/{estimateId}

Update a draft estimate.

Scope
estimates:write
Effect
Writes a draft or record
MCP tool
update_estimate
Retries
No Idempotency-Key on this route

Parameters

Update parameters
NameInTypeNotes
estimateIdrequiredpathid—

Request body

JSON. Money is an integer count of minor units beside its currency; quantities are thousandths.

Update request body
FieldTypeNotes
expectedUpdatedAtoptionalstringup to 40 chars
lineItems[]optionalobject[]up to 200 items
lineItems[].idoptionalid—
lineItems[].descriptionoptionalstringWhat the line is for. Optional with a presetKey (the item’s name is used). — up to 2000 chars
lineItems[].quantityMillioptionalintegerQuantity in thousandths: 1000 is one unit, 1500 is 1.5 hours. Defaults to 1000.
lineItems[].rateBasisoptionalenumHow the price applies: fixed for one flat charge, hourly, daily, perUnit, percentage… Optional with a presetKey. — One of fixed, hourly, daily, weekly, monthly, perUnit, perMile, perKilometre, percentage
lineItems[].unitPriceoptionalobjectPrice per unit in integer minor units of the document currency ($5,000.00 is 500000).
lineItems[].unitPrice.minorUnitsrequiredinteger—
lineItems[].unitPrice.currencyrequiredCurrency—
lineItems[].rateBasisPointsoptionalinteger—
lineItems[].taxTreatmentoptionalstring—
lineItems[].taxRateBasisPointsoptionalinteger—
lineItems[].discountBasisPointsoptionalinteger—
lineItems[].presetKeyoptionalstringThe key of one of the business’s products and services (get_business_context lists them); the server fills what the line leaves out. — up to 64 chars
notesoptionalstringup to 4000 chars
issueDateoptionalstringmatches ^\d{4}-\d{2}-\d{2}$
validUntiloptionalstringmatches ^\d{4}-\d{2}-\d{2}$

Returns

data: Estimate

Errors this route can answer besides the shared ones: ACTION_PENDING_ON_TARGET, NOT_A_DRAFT.

Example requestSample
curl -X PATCH "https://api.billingmart.com/v1/estimates/{estimateId}" \
  -H "Authorization: Bearer $BILLINGMART_API_KEY"

estimates

Convert

POST/v1/estimates/{estimateId}/convert

Convert an ACCEPTED estimate into a draft invoice (its lines re-derived). Nothing is sent. Refused unless the estimate is accepted; nothing in this API marks one accepted yet.

Scope
estimates:write
Effect
Writes a draft or record
MCP tool
convert_estimate_to_invoice
Retries
Send an Idempotency-Key; a repeat replays the stored answer for 24 hours

Parameters

Convert parameters
NameInTypeNotes
estimateIdrequiredpathid—

Returns

data: object

Errors this route can answer besides the shared ones: INVALID_TRANSITION.

Example requestSample
curl -X POST "https://api.billingmart.com/v1/estimates/{estimateId}/convert" \
  -H "Authorization: Bearer $BILLINGMART_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"

estimates

Discard

POST/v1/estimates/{estimateId}/discard

Discard a never-numbered DRAFT estimate. Refused once numbered, or while an action on it is pending.

Scope
estimates:write
Effect
Writes a draft or record
MCP tool
discard_draft_estimate
Retries
Send an Idempotency-Key; a repeat replays the stored answer for 24 hours

Parameters

Discard parameters
NameInTypeNotes
estimateIdrequiredpathid—

Returns

data: object

Errors this route can answer besides the shared ones: NOT_A_DRAFT, ACTION_PENDING_ON_TARGET.

Example requestSample
curl -X POST "https://api.billingmart.com/v1/estimates/{estimateId}/discard" \
  -H "Authorization: Bearer $BILLINGMART_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"

Object

Estimate

A quote. Sending one counts as a send toward the plan’s monthly allowance and is never blocked, even at the limit. Acceptance does not create an invoice: conversion is a separate, human act, which is why convertedInvoiceId is optional and set by the server.

Estimate fields
FieldTypeNotes
idrequiredId—
tenantrequiredTenantRef—
numberoptionalstring—
clientIdrequiredId—
clientrequiredInvoiceClientSnapshot—
statusrequiredEstimateStatus—
currencyrequiredCurrency—
languagerequiredLanguage—
issueDateoptionalDateOnly—
validUntiloptionalDateOnly—
lineItemsrequiredLineItem[]—
customFieldsoptionalobjectUntrusted textkey, exactly as on an Invoice: typed against the business model, unknown keys dropped, never free-form.
totalsrequiredInvoiceTotals—
notesoptionalstringUntrusted text—
internalNotesoptionalstringUntrusted textINTERNAL. Never crosses to a public link.
termsoptionalstringUntrusted text—
acceptedAtoptionalIsoTimestamp—
acceptedByNameoptionalstringUntrusted textWho accepted, as typed by the customer. Evidence, not identity.
declinedAtoptionalIsoTimestamp—
convertedInvoiceIdoptionalId—
createdAtrequiredIsoTimestamp—
updatedAtoptionalIsoTimestamp—
createdByoptionalId—
discardedAtoptionalIsoTimestamp. Set by a function when a never-numbered draft is discarded: it leaves every default list and cannot be sent or opened. Soft, never a status value (a money-enum addition is a breaking change).
discardedByoptionalId. The uid or credential that discarded it.
lastWriteActoroptionalWriteActor—
jobIdoptionalIdThe work record this belongs to, when it does. FUNCTION-WRITTEN: set by the callables that check the record is in the same business, never by a payload alone.
Next section

Payments

What was paid, how, and what is still owed. Recording and refunding are API-key scopes or approved actions, never a connected assistant on its own.

Continue to Payments →

Try it against your sandbox

Create a bmk_test_ key in the console. It can only reach your sandbox workspace.

We use Google Analytics on our website by default to understand visits. Choose Decline to turn it off; you can change this at any time on the Cookies page. We never send Google your name, email or account. Cookie policy