July 2026
- Breaking:
agentTypeon the Agents module is now a campaign type, not a combined template id. Create agent, theagentTypefilter on List agents, and the agent responses accept and returnoutreach,inbound, orappointment. What the agent can do moved to a separate field,capabilityIdson create, which takes one or more ofappointment_booking,live_transfer, andadd_tag. The seven combined ids listed under “Agent types are now a fixed, validated set” below are no longer accepted asagentType; sending one now returns a 400 listing the three valid types. Integrations that send a combined id assystem, with noagentType, are unaffected and keep working. See Campaign types and capabilities for the mapping from each old id to its type and capability set. - A campaign’s installed capabilities are now readable. Agent responses
carry
capabilitieson the campaign facet, so you can tell what an agent can do without inferring it from a template id. Capabilities also gate outcomes: a call can only end inTRANSFERwhen Live Transfer is installed, and inSUCCESSorRESCHEDULEwhen Appointment Booking is. GET /api/agent-builder/agent-typesreturns three entries, not seven. Outreach and Inbound each carry atemplatesarray listing the starting capabilities you can pass ascapabilityIds. Reminder resolves to a single fixed template.- The Campaigns and V2 Projects modules still speak the seven template ids.
Their
agentTypeis unchanged and still validated against the original set. It names the template a campaign was cloned from, not what the agent can do, and on an agent created with several capabilities it reflects only the first. These modules will be migrated separately; until then, treatagentTypeon the Agents module andagentTypeon Campaigns/Projects as different fields that happen to share a name. - Appointment Booking is now a documented skill type. It was already
installable and has been all along, but the reference omitted it from the
skill type set and from
GET /api/agent-builder/agents/{id}/skills/library. Both now list it. No behaviour changed; the documentation was wrong. - Breaking: call records answer with the canonical field names. A call’s
identifier is
idand its agent type isagentType. The storage spellings_idandcampaignSystemare no longer part of the response. The list payload also no longer carriescached,queryTime, andgeneratedAt— those described the server’s own caching, not your data, and were never something to build on. - Breaking: execution-history responses nest under
dataand use camelCase. The run summary, node history, runs list, timeline, and graph endpoints previously spread the run store’ssnake_caseat the top level of the response, which made an internal storage vocabulary the public contract. They now return{ "success": true, "data": { … } }with the same camelCase names the rest of the API uses. - Campaign workflows can now be addressed by the agent that owns them. A
workflow is reachable at
/api/agent-builder/agents/{agentId}/campaign/workflow, alongside endpoints to read a digest, append an action to an outcome, switch an outcome, and delete a node. The six project-scoped equivalents under/api/agent-builder/projects/{locationId}/campaigns/{campaignId}/…still work and are unchanged, but they are deprecated: they now carry aDeprecationresponse header (RFC 9745) and are marked deprecated in this reference. They will be removed in a future release — move to the agent-scoped paths. - Fixed: fetching a call by its platform call id.
GET /api/call-history/by-call-id/{callId}returned 404 for every call, including ones that exist. It now returns the call. - Fixed:
excludeReviewed=falseno longer excludes. The value was coerced in a way that read any present value as true, so passingfalsedid the opposite of what it says.excludeReviewednow takes exactlytrueorfalse, and any other value is a validation error rather than a guess.dispositionis also accepted as a repeated parameter again, not only as a comma-separated string. - A campaign’s
agentTypeanddialingare validated wherever a campaign is written. The project-scoped campaign routes accepted any string for either field and stored it, after which the campaign read back withagentType: nulland no way to tell from the write that anything was wrong. Both fields are now checked against the published sets on those routes too, and an unknown value is rejected with a 400 that lists the valid ones. - Agent types are now a fixed, validated set.
agentTypeaccepts onlyappointment_booking,appointment_confirmation,live_transfer,live_transfer_and_tag,live_transfer_and_booking,add_tag, andinbound_receptionist. An unrecognised value is now rejected up front as a validation error listing the valid types, instead of failing later as a not-found. The same set applies to theagentTypefilter on List agents. The agent type is also always present on an agent response now. It isnullwhen none can be resolved, where it was previously left out of the object. - Breaking: the
confirmationandreactivationdispatch modes are retired. Neither can be set on a campaign any more: creating or updating with"dialing": "reactivation"(or"confirmation") is rejected with a 400, and the writable modes are nows2l,pd, ands2l_pd. Campaigns created before this still work — they keep their stored mode, keep dialing exactly as before, and still report"dialing": "reactivation"on a read, which is why that value remains in the response schema. What they cannot do is have their dispatch mode re-sent: an update that includes the retired value is refused, so change the mode to a supported one in the same request if you need to edit such a campaign.confirmationhad no campaigns left at all and is gone from reads too; it previously surfaced aspd, and no longer does. - Breaking: a campaign’s
dialingno longer acceptsnull. Sending"dialing": nullwhen creating or updating a campaign is now rejected with a 400. Omit the field to leave a campaign’s current dispatch mode alone, or, on create, to take the default for the agent type (outbound types default topd). There is no “clear the dispatch mode” operation, because a campaign without one is inert: it never dials, and it also hides the controls you would use to set it, so it cannot be repaired from the dashboard. Any campaign already storing anullis re-derived to its correct mode on its next write. - Breaking: three campaign-workflow action types have been removed.
post-webhook,enroll-in-campaign, andrequeue-pdare no longer valid values for a workflow nodetype, and are rejected on write. The supported actions areadd-tag,remove-tag,set-field,move-stage,add-note,send-sms,send-email, andbook-appointment, plus theifandswitchbranch nodes. Re-dialling a contact who did not answer is handled by the engine itself and never needed a node. The webhook node’surl,payload,headers,auth, andretryconfig fields are gone with it, as is the[REDACTED]projection that existed only to hide its credentials. - Workflow configs are rejected if they contain an unreplaced placeholder.
A node config carrying a stand-in value (
REPLACE-WITH-…,CHANGE-ME, or a URL on a reserved documentation host such asexample.com) now fails to save. An empty config is still accepted — an unfinished draft is fine, a value that only looks finished is not. - Post-call analysis fields are now protected on update. When you update an agent, platform-managed analysis fields (the standard call outcomes and other system-managed fields) are always retained, even if your request omits them. A partial update that sends only your own custom fields no longer removes the managed ones. Only the custom fields you send are replaced.
- Added public API documentation for launched customer-facing modules.
- Added bearer API key authentication guidance.
- Added standard API response and error conventions.
