API changelog
The change history of the Cooledge API contract for integrators. Records each dated change to endpoints, fields and webhook events, and explains the versioning policy: additive changes ship without a version bump, breaking changes get a new API version.
API changelog
This is the change history of the Cooledge API contract: the endpoints, fields and webhook events you build against. It is for integrators who need to know when the API surface changes and whether a change can affect their code.
This is not the product "what's new". Customer-facing feature announcements live in the Cooledge changelog. This page only records changes to the API contract.
Versioning policy
The API is versioned by path, starting at v1 (for example /v1/customers). Two kinds of change can happen, and they are treated differently:
- Additive changes are backward compatible. New fields on a response, new optional request parameters, new endpoints and new webhook event types are all additive. They do not break code that does not use them, so they can ship inside the current version without a version bump and without a dated entry being required for every one. The most important consequence for you: tolerate unknown fields. Ignore any field or event type you do not recognise rather than failing on it, because new ones can appear at any time.
- Breaking changes get a new API version. Removing or renaming a field, changing a field's type or meaning, removing an endpoint or tightening validation in a way that rejects requests that used to work are all breaking. A breaking change ships under a new version path so your existing integration keeps working against the version it was built for. Every breaking change gets a dated entry on this page so you can see what moved and when.
When in doubt, code defensively: read the fields you need, ignore the rest and do not assume the set of fields or event types is fixed.
Changes
2026-11-01: invoice.sent carries the customer's due date
An invoice now gets its due date when it is first sent. due_date on invoice.sent is the date the customer was given: the date set on the invoice, or else the send day plus the business's payment terms. It used to be null on many invoices. It can still be null when the invoice has no date, such as a resend of an older invoice or an invoice created already paid. The field and its type are unchanged.
2026-10-13: Tasks API, MCP task tools and the Event booking type
The API can now read and manage tasks, the to-dos your team keeps in Cooledge. The tasks endpoints, scopes and MCP tools are additive. The booking type rename changes an output value, covered at the end of this entry.
- Two new scopes.
tasks:readreads tasks.tasks:writecreates, updates, completes and reopens them. Both are in the OAuth default scope set for new connections. Existing keys and connections gain nothing: create a new key with the Tasks row ticked, or disconnect an older OAuth connection and connect it again. See Authentication. - New endpoints.
GET /v1/tasksandPOST /v1/tasks,GET /v1/tasks/{id}andPATCH /v1/tasks/{id},POST /v1/tasks/{id}/completeandPOST /v1/tasks/{id}/reopen. A task has a title, description, assignee, a due date or date and time, one reminder, a link to one job, quote, lead or customer and an optional repeat.assignee_idtakes"me"only on an OAuth connection, where it means the person who approved it. An API key acts as the business, so"me"orview=minegets a 400. Completing a task that is already done changes nothing, so retries are safe. There is no delete endpoint and no attachments inv1. The API reference has every field. - Five MCP tools.
list_staff,list_tasks,create_task,update_taskandcomplete_task, bringing the server to 36 tools. See MCP server. - The booking type is now
joborevent. An Event is a calendar block with no job, and a block for a scheduled task is an Event too. Responses (including bookings embedded in a job), thebooking.createdwebhook and the MCP booking tools now sayeventwhere they used to saytask. On input,task,reminder,meetingandotherare still accepted onPOST /v1/bookings,PATCH /v1/bookings/{id}andcreate_booking. They are stored as an Event. OnGET /v1/bookings,booking_type=eventandbooking_type=taskboth return Events.
Under the versioning policy above, changing an output value from task to event is a breaking change. It ships in v1 because no integration had used task bookings through the API, OAuth or webhooks when it was made. Every request that worked before still works. If your code reads booking_type, treat event as the value for any booking without a job.
2026-10-13: Message HTML is cleaned before it reaches you
html on a message is now cleaned by Cooledge in GET /v1/conversations/{id}/messages, the MCP tools that read messages and the message.received and message.sent webhooks. Scripts, style blocks, forms and embedded content are removed. Links keep only http, https, mailto and tel addresses and open in a new tab. Images keep only http, https, cid and data:image sources. Cooledge still keeps each email exactly as it arrived. The field shipped on 2026-10-11 and changed before integrations were built on it, so it stays in v1.
2026-10-11: Messaging API and drafts
The API can now read the team inbox and write reply drafts that a person reviews and sends in Cooledge. Nothing in the API sends a message. These are additive changes, so existing integrations are unaffected. See the Messaging API guide.
- Two new scopes.
messages:readreads conversations, messages and drafts.messages:draftcreates, updates and deletes drafts and never sends. Neither is in the OAuth default scope set. Existing keys and connections gain nothing. On the key screen they are the new Messages row. See Authentication. - New endpoints.
GET /v1/conversations,GET /v1/conversations/{id},GET /v1/conversations/{id}/messages,GET /v1/drafts,POST /v1/drafts,GET /v1/drafts/{id},PATCH /v1/drafts/{id}andDELETE /v1/drafts/{id}. A draft always goes to the conversation's own party, with noto,cc,bccor files. The body is strict, so an unknown field is a 400. Drafts from apps are capped at 3 waiting per conversation and 200 per business, answering 429 with the typeurn:cooledge:error:draft-cap. - Six MCP tools.
list_conversations,get_conversation,list_drafts,create_draft,update_draftanddelete_draft, bringing the server to 31 tools. See MCP server. - Two webhook events.
message.receivedfor an inbound text or email, usually within a few minutes of it arriving.message.sentfor a text or email the team sends from Messages, with adraftfield when it was a draft.message.sentis best effort, so a rare event can be lost. - Subscriptions to message events need
messages:read. Through the API, creating a subscription that includes either message event needsmessages:readas well aswebhooks:manage. So does an update that leaves either event on the subscription, rotating its secret or deleting it. Separately, an update to any subscription that loses a race with another change now answers 409, so read it again and retry. See the events index.
2026-07-15: MCP server with OAuth connect
Cooledge now runs a remote MCP server at https://app.cooledge.com.au/api/mcp/mcp, so Claude, Cursor, ChatGPT and other MCP clients can work with your Cooledge data. It exposes 25 tools over customers, jobs, quotes, invoices, bookings and leads, and every call runs the same scopes, plan checks and rate limits as the REST API. See MCP server.
Alongside it the platform gains OAuth 2.1 endpoints: dynamic client registration at POST /api/oauth/register, authorization at /oauth/authorize, token exchange at POST /api/oauth/token and discovery metadata at /.well-known/oauth-authorization-server. OAuth access tokens are bearer tokens with the ccoat_ prefix and also authenticate v1 REST calls. These are additive changes, so nothing changes for existing API-key integrations.
2026-06-28: opt-in lead notifications on create
POST /v1/leads now accepts an optional notify boolean. It defaults to false, so nothing changes for existing integrations. Set it to true to send the business owner the same new-lead email and push notification that the chat widget and website forms send, which is what you want when a lead comes from a connected form or app. Leave it off (or omit it) for bulk imports and syncs so the owner is not flooded with alerts. The business's own lead-notification email setting still applies, so an owner who has turned those emails off will not get one even when you pass notify: true.
2026-06-23: lead lifecycle events reworked
The lead events now track the lead's real lifecycle from capture to won. These are additive and meaning-preserving for the event names, but the lead payloads changed, so check the notes below if you consume them.
- New
lead.wonevent. A lead now reports when the deal is won. It fires once, when a quote is accepted, when a quote is paid, when the first invoice is paid on a lead that never had a quote or when the lead is marked won manually. Creating a job does not win a lead. See lead.won. lead.convertedredefined. It now fires once when a lead becomes an active opportunity, meaning its first quote or job is created or it is qualified manually. It no longer fires on customer linking at creation. The payload dropscustomer_was_createdand addsconverted_via(quote,jobormanual),quote_idandjob_id. See lead.converted.lead.creatednow fires for every owned lead. It fires for leads from the portal, your website forms, the API and inbound GoHighLevel, not only API and GoHighLevel leads. The payload fieldtypeis renamed tolead_type(for exampleinboundormarketplace) and thesite_idfield is removed.customer_idis usually null at creation. See lead.created.- v1 leads-create parameter renamed. On
POST /v1/leadstheauto_convertfield is renamed toauto_create_customer, which is what it actually controls.
2026-06-17: v1 initial release
The first public version of the Cooledge API. The launch surface is:
- Resources. Read and manage customers and their sites, jobs, quotes, invoices, bookings and leads, plus the
/v1/meidentity endpoint that returns the business a key belongs to and the scopes it holds. - Webhook events. Twelve event types across customers, leads, quotes, invoices, jobs and bookings, listed in full on the events index. Every delivery is signed and carries a stable event id for deduping.
- Cursor pagination. List endpoints return a
dataarray and anext_cursor, paged with an opaque cursor. See Pagination and errors. - RFC 7807 errors. Every error response is problem-details JSON with a stable
typeURN, astatusand an optionaldetail. See Pagination and errors. - API-key authentication. Requests are authenticated with the
X-Api-Keyheader. See Authentication for the key format and the scope list.
Where to go next
- Getting started walks through your first call.
- The API reference is the endpoint-by-endpoint specification.
- The events index lists every webhook event type.
Need a hand with an integration? Contact support