Changelog
The API is in beta, and it can change without advance notice. This page records every change. Watch it, and you see what moved, and when it moved.
The newest entry is first. Each date is the day that the change reached production.
2026-10-27
- Added:
buydown_reasonon a commission, the broker's note on why they bought the rate down. You can read it, and you can set it withPOSTorPATCH /v1/deals/{id}/commission. It is optional.
2026-10-21
- Added: a contact relationship's
typecan be a professional the client keeps:realtor,lawyer,appraiser,accountant,financial_planner,insuranceorbuilder. Thelabelis worded from the contact you read, so the professional readsLawyerand the client readsClient. - Added:
GET /v1/opportunitiestakes the filters from the book in BrokerPlus:dismissed,archived,maturity_fromandmaturity_to(a maturity window,YYYY-MM-DD),opportunity_type,product_type,start_year, andassigned_broker_id. It also takessort, which orders the list by maturity date or by the client's last message. A list filter takes values separated by commas, and an unknown value gets400 VALIDATION_ERROR. - Added:
modeon afield,checkpoint, orcustom_fieldrequirement of a pipeline stage.cumulativeis the default and applies the requirement to the stage and to every later stage, as before.this_stageapplies it to the stage only.optionalasks the broker for it when they move a deal into the stage, but does not stop the move. If you read requirements and send them back, keepmode, or an optional requirement becomes required. - Changed: a
checkpointrequirement withrequired: falsenow reads asmode: "optional". The broker sees the step when they move a deal into the stage, and the move still goes ahead. Amodethat you send on acheckpointwins overrequired. - Added: a stage requirement of kind
custom_field. Itskeyis one of your deal custom fields, and the deal must have an answer before it moves into the stage. A checkbox counts only when it is ticked.GET /v1/deals/{id}/stage-requirementsand a409 STAGE_REQUIREMENTS_UNMETname a missing custom field withkind: "custom_field". - Added: each
provincethat takes a numeric code also takes the two-letter code, for exampleONin place of50. This applies to the subject property, an employment, and an applicant address. On read, these provinces also haveabbreviation, the two-letter code. - Changed: an other property's
provincetakes only a province: the two-letter code, or the numeric code, which is saved as the two-letter code. Any other value gets400 VALIDATION_ERROR, and the error lists the accepted values. It used to save any text. - Added:
PATCH /v1/deals/{id}takestype, with the same values asPOST /v1/deals. The change is the same as in the dashboard: BrokerPlus calculates the total loan amount and the mortgage insurance premium again, and a change that crosses a renewal type replaces the renewal disclosures. The deal stays on its pipeline and in its stage. - Added:
GET /v1/dealstakesstage_idandboard_id.stage_idreturns only the deals in that stage, andboard_idreturns only the deals on that pipeline. Use them withupdated_sinceto sync one stage. - Changed:
POST /v1/opportunitiesno longer requiresterm_months. Without a term, BrokerPlus does not estimate the balance. The opportunity uses thebalancethat you send, ormortgage_amountwhen you do not sendbalance. - Added: an automation's email step can name a role on the deal in
toRecipients,ccRecipientsandbccRecipients, for exampledeal-role:Closing Officer. The email goes to the teammate who holds that role on the deal. Only a trigger that runs on a deal accepts it.
2026-10-20
- Changed: an automation's
type_label, and each trigger's name inGET /v1/automations/catalog, is now in title case, the same as on screen.Deal moved into a stagereadsDeal Moved into a Stage. Thetypevalues did not change, so match ontyperather than on the name.
2026-10-19
- Added: a captured answer's
sourcecan bemeeting. It is an answer the client gave in a meeting that the notetaker recorded, and itscommunication_idis that meeting. - Added: a lead's
sourceand a contact'screated_viacan beassistant: a person the broker's assistant added to their book. - Changed:
POST /v1/contactswith a name and a phone number fills in the contact that holds only that number, if there is one, and returns it. It used to add a second contact beside it. - Changed: a communication folder from an Outlook mailbox can now have a
parent_id. Outlook folders used to arrive withparent_idset to null. They now name the folder they sit in, the same as in Outlook, and that folder can be a system folder such as the inbox.
2026-10-17
- Changed: an employment's
typeno longer has the temporary codes. The codes are now 1 (permanent full time), 2 (permanent part time), 5 (seasonal) and 7 (not applicable). A job saved as temporary full time (3) now reads as 1, temporary part time (4) as 2, and temporary seasonal (6) as 5. A request that sends 3, 4 or 6 is still accepted, and saves 1, 2 or 5 in the same way. - Added: a lead's
sourceand a contact'screated_viacan bemeeting: a person the broker met in a meeting and then added to their book.
2026-10-13
- Added: an outreach template returns
body_html, the formatted version of an email template.PATCH /v1/outreach-templates/{id}takesbody_htmlto change it, or null to go back to plain text. A newbodywithout a newbody_htmlstill removes the formatted version. - Added: a credit report's
statuscan beno_score. It is a credit check that the system the deal came from ran, which returned no score. You can still pull credit for that borrower. - Changed: on a second or later charge against a home the borrower already owns,
ltvonGET /v1/deals/{id}/applicationis the combined loan to value (CLTV). It counts the balance of each mortgage and home line of credit ahead of the loan, the way a lender reads it. On a first charge it is the loan alone, as before. When the deal cannot say which charge is ahead,ltvstays the loan alone. - Added:
GETandPATCH /v1/deals/{id}/propertyreturnlending_value_basisandestimated_value. When a file names the value it lends against (price,estimate, orappraisal),ltvonGET /v1/deals/{id}/applicationis worked out on that value while the deal holds it, on a refinance, switch or renewal. A purchase, and any file that names no value, is still worked out on the lower of the purchase price and the appraised value. - Changed: when
loan_amountonGET /v1/deals/{id}/applicationalready holds the default insurance premium,total_loan_amountisloan_amountand the premium is not added a second time. A loan holds it when it is within one dollar of the purchase price less the down payment plus the premium, or of Finmo's own total for the loan.insurance_premium_rateis then a percent of the loan before the premium, which istotal_loan_amountminusinsurance_premium. With no property value, a premium on file is added only on a deal that started in Finmo. On any other dealtotal_loan_amountis thenloan_amount. - Fixed: ChatGPT finishes connecting to the MCP server. A client whose metadata document
names
private_key_jwtand also listsnoneintoken_endpoint_auth_methods_supportedcan get its token with PKCE alone. If it sends aclient_assertion, the assertion is checked. - Fixed: a connected app keeps its connection while its metadata document can't load. A public
client's refresh no longer reads the document. A
private_key_jwtclient uses the last keys that loaded, for up to 24 hours.
2026-10-12
- Breaking: a key with the
no_sendinglimit now gets403 KEY_LIMITEDon the requests that show a client something at once:POST /v1/hub-resources,POST /v1/tracker-stages,PATCH /v1/tracker-stages/{id},POST /v1/tracker-stages/reorder,POST /v1/tracker-stages/seed, andPATCH /v1/tracker-stages/note. Reading and removing stays open. See Reaching clients. - Changed: the MCP server covers the whole API. Every operation is now a tool, deletes, setup, webhooks, batch writes, signed links, and compliance records included. The tool's MCP annotations tell your assistant what to confirm with you: a delete is marked destructive, and a tool that reaches a client or anybody else outside the brokerage is marked destructive and open-world.
- Changed: the MCP server hides every tool that the key's limits refuse. A key with the
no_sendinglimit no longer sees the tools that reach a client, and a read-only key still sees only the tools that read. The API refuses these calls the same way as before. - Changed: the MCP tool list is under 1 MB, so Claude and ChatGPT connectors load every tool. A
listed
outputSchemanames onlydataandpagination, and descriptions stop after their first sentences.brokerplus_describe_operationreturns the full contract of any operation. - Changed: ChatGPT connects to the MCP server. The authorization server now accepts
private_key_jwtclient authentication from a client that declares it in its Client ID Metadata Document, and it lists the method intoken_endpoint_auth_methods_supported. - Added: reply to a client.
POST /v1/communications/{id}/replyanswers an email or text in its own conversation, from the mailbox or number the conversation is on, withmodereply,reply_all, orforward, and files inattachments. It reaches the client, so a key with theno_sendinglimit is refused it.POST /v1/communications/{id}/draftswrites the same reply into the broker's drafts and sends nothing. - Added:
PATCH /v1/drafts/{id}edits a draft,POST /v1/drafts/{id}/discarddiscards one, andPOST /v1/drafts/{id}/scheduleandPOST /v1/drafts/{id}/unscheduleset and stop a send time. Scheduling reaches the client, so a key with theno_sendinglimit is refused it. - Added:
send_atonPOST /v1/contacts/{id}/messagesandPOST /v1/communications/{id}/replysends the message later. - Added: the draft object returns
to,cc,bcc,reply_to_communication_id,forward, andattachments. - Added: a forward on
POST /v1/communications/{id}/replyandPOST /v1/communications/{id}/draftscarries the files of the email it forwards. Sendinclude_attachments: falseto leave them out. - Changed: the draft object's
contact_idis null for a reply or forward to an address that is not a contact. It was always a contact before. - Changed:
POST /v1/drafts/{id}/sendalso sends a draft with no contact, such as a reply to a lender.
2026-10-11
- Added: a campaign can go to several audiences.
segment_idsonPOST /v1/campaignsandPATCH /v1/campaigns/{id}takes up to 20 more audiences next tosegment_id, and a person in more than one of them gets one message. The campaign object returns every audience insegment_ids;segment_idis now the first of them. - Changed: a recipient variable such as
{{borrower.firstName}}no longer needs a fallback. A contact with no value gets a blank. - Changed:
POST /v1/campaigns/{id}/schedulereturns422withSENDER_DETAIL_MISSINGwhen the campaign names a sender detail, such as{{broker.phone}}, that the broker's profile leaves empty.
2026-10-10
-
The notetaker can be sent from the API:
POST /v1/meetingssends it into a call,POST /v1/meetings/{id}/stoptakes it out, andPOST /v1/meetings/{id}/syncpulls the transcript again. Sending it reaches clients, so a key with theno_sendinglimit is refused it. -
Date triggers can be set up and switched on and off:
POST /v1/pulse-triggers(lands off),PATCH /v1/pulse-triggers/{id}(movesdays_offset),POST /v1/pulse-triggers/{id}/turn-on, andPOST /v1/pulse-triggers/{id}/turn-off. Turning one on reaches clients, so a key with theno_sendinglimit is refused it. -
The reference now describes the
urgent,normal, andlowfields of a compliance program'salert_routing, andGET /v1/intakes/{id}/notes/{noteId}. Nothing about them changed. -
Breaking: requests that reach a client act at once, and approvals are gone. A request that emails, texts, books, or otherwise reaches a client no longer waits for the broker's approval. It runs now, as the broker your key acts as, and returns the record it made or changed. A key with the
no_sendinglimit is still refused every one of these requests, so use that limit for any key that must not contact clients. See Reaching clients. What changed:GET /v1/approvals,GET /v1/approvals/{id}, andPOST /v1/approvals/{id}/cancelare removed, with the approval object and theapproval.approvedandapproval.rejectedwebhooks.- These returned
202with an approval, and now return201with the new record:POST /v1/contacts/{id}/messages(the sent draft),POST /v1/deals/{id}/condition-requests(the sent draft),POST /v1/deals/{id}/generated-documents/{documentId}/send(the sent draft),POST /v1/mail-merges(the mail merge),POST /v1/appointments/book(the booking),POST /v1/nps-surveys(the survey),POST /v1/pep-forms(the form),POST /v1/deals/{id}/consent-forms(what was sent),POST /v1/deals/{id}/document-requests(the document requests it added), andPOST /v1/deals/{id}/funding-package/send(the signing envelope). - These returned
202with an approval, and now return200with the record they changed:POST /v1/drafts/{id}/send(the draft),POST /v1/automation-runs/{id}/start(the run),POST /v1/campaigns/{id}/schedule(the campaign, withwarnings),POST /v1/appointments/{id}/rescheduleandPOST /v1/appointments/{id}/cancel(the booking),POST /v1/intakes/{id}/request-changes(the intake),POST /v1/deals/{id}/signing-documents/send(the signing documents),POST /v1/deals/{id}/signing-documents/{documentId}/resend(the signing document),POST /v1/deals/{id}/tracker/{stageId}/reach(the tracker),POST /v1/automations/stops/{id}/lift({ id, deleted: true }), andPOST /v1/equity-reports/enroll,/resume, and/send(a line for each deal,changed,unchanged, orrefused). POST /v1/automations/{id}/turn-onandPOST /v1/lead-forms/{id}/turn-on-auto-replyalways return200with the automation or the form.POST /v1/automations/canvases/{id}/turn-onturns on every automation in the group, and its results no longer carryapproval_idorapproval_requested.POST /v1/intakeswithdelivery: "email"emails the intake at once, and the response no longer hasapproval_id.- Two new errors:
403 FORBIDDENwhen the person your key acts as cannot send this in BrokerPlus either, and409 NOT_SENTwhen the request could not go out as it stands. Nothing was sent in either case. - Your brokerage's automation policy still applies: where it does not allow messages to clients to
be asked for this way, each of these requests answers
403 POLICY_BLOCKEDand sends nothing. - MCP tools that reach a client are now marked
destructiveHintandopenWorldHint, so an assistant asks its user before it calls one.
-
A merged deal stays archived. When BrokerPlus merges a spreadsheet copy of a Finmo file into the Finmo deal, the copy is archived and its work moves to the Finmo deal.
POST /v1/deals/{id}/restoreon that copy returns409with the codeMERGED, and the copy stays archived. -
Every Canada Post street type.
street_typeon an address now takes and returns every Canada Post street type, English and French, 182 in all, where it took 26. The numeric codes it already used keep their meaning. -
Notes on an intake.
GET /v1/intakes/{id}/noteslists the notes brokers wrote on an intake's files and items,GET /v1/intakes/{id}/notes/{noteId}reads one, andPOST /v1/intakes/{id}/noteswrites one or replies to one. The client never sees them. The MCP server has a tool for each. See Write notes on an intake. -
Bank statement transactions.
GET /v1/intakes/{id}/transactionslists the transactions on a client's bank statements with the broker's changes,POST /v1/intakes/{id}/transactions/overridetakes them out of the income calculation or recategorizes them, andDELETE /v1/intakes/{id}/transactions/{transactionId}/overrideundoes that. Nothing goes to the client, and an account number is only ever its last 4 digits. The MCP server has a tool for each but the undo. See Take out or recategorize a transaction. -
What the income calculation counts.
GET /v1/intakes/{id}/stated-income-scopereads the broker's choices on the stated income card (the dates, the statements and accounts left out, the income the client declared) and the bank accounts on the statements, andPATCHchanges them. Nothing goes to the client. The MCP server has a tool for each. See Shape the income calculation. -
Tracker links.
GET /v1/deals/{id}/tracker/linkslists the links that still show a deal's tracker to a realtor or a lawyer, andPOST /v1/deals/{id}/tracker/links/{linkId}/revoketakes one back. BrokerPlus no longer makes new ones: a partner gets a partner hub. The MCP server has a tool for each. See Tracker links. -
Media library.
/v1/media-assetslists the pictures and video stills the brokerage keeps for outreach emails, uploads a picture, adds a video link, and deletes one. The MCP server has a tool for each but delete. See Media library. -
Outreach templates.
/v1/outreach-templatesreads and writes the first-touch emails and texts a broker sends by hand from the refinance, renewal and lead lanes: the broker's own set and their team's, with set-primary, duplicate, share and copy-to-personal, as the outreach templates editor has. Nothing sends. The MCP server has a tool for each but delete. See Outreach templates. -
Retention signals.
GET /v1/pulse-signalslists the reasons BrokerPlus raised to reach a past client now, an equity drop or a date of theirs, andGET /v1/pulse-triggersreads the broker's date triggers. Both are read-only. The MCP server has a tool for each. See Retention signals. -
A locked deal refuses opportunity changes.
PATCH /v1/opportunities/{id}on a deal in a stage that locks it now answers403 DEAL_LOCKEDfor every figure, not onlysegments, as BrokerPlus does.nameand the rate assumptions (comparison_rate,effective_penalty,penalty_type,cashback_enabled,cashback_override) can still change. -
Recorded meetings.
GET /v1/meetingslists the video meetings BrokerPlus took notes in, with its summary, andGET /v1/meetings/{id}adds the transcript, who spoke and for how long, the follow-ups, and the meeting chat. The recording itself is not on the API. The MCP server has a tool for each. See Read recorded meetings. -
An automation run's steps.
GET /v1/automation-runs/{id}/stepslists what each step of a run did or will do: the draft it wrote, the message it sent, the task it made, or why it was skipped. The MCP server has a tool for it. See Read the runs. -
Creditor life insurance.
GET /v1/deals/{id}/life-insurancereads the deal's creditor life insurance, andPOST /v1/deals/{id}/life-insurance/outcomerecords what the client said when the broker offered it. Nothing is sent to the insurer. The MCP server has a tool for each. See Creditor life insurance. -
Credit consents lapse after 30 days. A
credit_pullconsent now always has anexpires_at, 30 days aftergranted_at, however it was captured. OnPOST /v1/deals/{id}/consents, an earlierexpires_atis kept and a later one is cut to 30 days. Credit consents that had no expiry took the same 30 days from their own grant date, so one given more than 30 days ago now reads as expired. -
Clients' equity report corrections.
GET /v1/equity-report-changeslists the corrections clients made to their equity reports, andPOST /v1/equity-report-changes/{id}/acceptand/declineanswer one waiting for the broker, as the report changes queue does. Neither sends anything to the client. The MCP server has a tool for each. See Answer a client's correction. -
Send a funding package for signature.
POST /v1/deals/{id}/funding-package/sendasks the broker to send the package. The response is202with a pendingfunding_package.sendapproval, bound to the package as it is.GET /v1/deals/{id}/signing-envelopesandGET /v1/deals/{id}/signing-envelopes/{envelopeId}read the envelopes that went out, each with itssigning_envelope_recipientlist. The MCP server has a tool for each. See Send it for signature. -
Mail merges.
POST /v1/mail-mergesasks the broker to send one email to each address on a list, each person on their own copy. The response is202with a pendingmail_merge.sendapproval that covers the whole list.GET /v1/mail-merges,GET /v1/mail-merges/{id}andGET /v1/mail-merges/{id}/recipientsshow what became of each address. An approval'starget.typecan now beuser. The MCP server has a tool for each. See Mail merges. -
Credit notes.
GET /v1/deals/{id}/credit-noteslists the broker's notes on the credit of the people on a deal, andPATCH /v1/deals/{id}/credit-notes/{contactId}writes one. Only the broker's words are returned: no credit score or report. The MCP server has a tool for each. See Credit notes. -
Consent forms.
GET /v1/deals/{id}/consent-formsandGET /v1/deals/{id}/consent-forms/{formId}read the consent forms emailed to the borrowers on a deal: the scope, the words, the status, and the consent that a signature recorded.POST /v1/deals/{id}/consent-formsasks the broker to email one: the response is202with a pendingconsent_form.sendapproval. The MCP server has a tool for each. See Ask a borrower for consent. -
What a client said on a call.
GET /v1/contacts/{id}/captured-answerslists the intake answers BrokerPlus heard on a call or in an email, with what the client said word for word inheard_as. Addpending=truefor the ones the next intake will fill in. The MCP server has a tool for it. See Read what the client said on a call. -
Goals.
GET,POST /v1/goalsandGET,PATCH,DELETE /v1/goals/{id}read and set the broker's goals from the Business pages: funded volume, funded deals or commission over a period, for the whole book or one lender. Each goal carriespace, where the broker stands today. The MCP server has a tool for each, except delete. See Goals. -
Introductions to a partner.
GET,POST /v1/partner-introductionsandGET,DELETE /v1/partner-introductions/{id}read and record the clients and leads a broker introduced to a referral partner. Nothing is sent. The MCP server has a tool for each, except delete. See Introductions to a partner. -
Partner firm notes.
GET,POST /v1/partner-company-notesandGET,PATCH,DELETE /v1/partner-company-notes/{id}read and write the brokerage's note on each partner firm, as on the Partners page. The MCP server has a tool for each, except delete. See Partner firm notes. -
Imports.
GET /v1/import-runsandGET /v1/import-runs/{id}follow the imports on the broker's teams, andPOST /v1/import-runs/filesadds a deals file to the team's open import. Nothing reaches the book until the broker reviews the import in BrokerPlus.GETandPATCH /v1/import-status-routesread and save where an import puts a deal by its status word.GET /v1/import-mappings,GET,PATCHandDELETE /v1/import-mappings/{id}read and change the column mappings saved from past imports; only an admin's key changes one. The MCP server has a tool for each, except delete. See Imports. -
Data exports.
POST /v1/data-exportsrequests an export of one package of the broker's records,GET /v1/data-exportsandGET /v1/data-exports/{id}follow it, andPOST /v1/data-exports/{id}/cancelstops it.GET /v1/data-exports/packageslists the packages you can export. The broker downloads the files in BrokerPlus. The MCP server has a tool for each. See Data exports. -
Team chat.
GET /v1/direct-threadslists the broker's team chat conversations, andPOST /v1/direct-threadsopens one with a teammate or starts a group.GETandPOST /v1/direct-threads/{id}/messagesread and post messages, andPOST /v1/direct-threads/{id}/readmarks a conversation read.GET /v1/direct-threads/rosterlists who the broker can message. A key reaches only the conversations its broker is in. The MCP server has a tool for each. See Team chat. -
Documents on a condition. A condition now lists the documents attached to it in
documents, andPOST /v1/conditions/{id}/documentsattaches more from the same deal. Nothing is sent. The MCP server has a tool for it. See Conditions. -
Report templates and bulk reports.
GET,POST /v1/report-templatesandGET,PATCH,DELETE /v1/report-templates/{id}read and write the brokerage's report builder templates.POST /v1/bulk-report-runsmakes one PDF report for each deal from a template or a layout, andGET /v1/bulk-report-runsandGET /v1/bulk-report-runs/{id}follow the runs.GET /v1/bulk-report-runs/{id}/filesgives links to the PDFs and the ZIP file. Nothing is sent to a client. The MCP server has a tool for each, except delete and the file links. See Reports and data. -
Files that came in by email.
GET /v1/deals/{id}/email-attachmentslists the files from a client's email that wait for the broker before they go on the deal file, with astatusfilter.POST .../acceptputs one on the deal file as a document, andPOST .../dismisskeeps it off. The MCP server has a tool for each. See Files that came in by email. -
Addresses and phone numbers on an applicant.
GET /v1/deals/{id}/applicants/{applicantId}now returnsaddresses, the applicant's address history with dates and a mailing address, andphones, the numbers the lender sees.POST /v1/deals/{id}/applicants/{applicantId}/addressesadds an address, andPATCHandDELETEon.../addresses/{addressId}change or remove one. The same three work on.../phones. The MCP server has a tool for each, except delete. See Edit the application one row at a time. -
PEP declaration forms.
GET /v1/pep-formsandGET /v1/pep-forms/{id}read the politically exposed person (PEP) forms sent to clients: the status, and the client's answers.POST /v1/pep-formsasks the broker to email the form to a client: the response is202with a pendingpep_form.sendapproval. The MCP server has a tool for each. See Ask a client to declare PEP status. -
Lender commitments.
GET /v1/deals/{id}/commitmentsandGET /v1/deals/{id}/commitments/{commitmentId}return the terms BrokerPlus read from the lender's commitment PDF, with the broker's corrections and the cost of borrowing.POST /v1/deals/{id}/commitmentsreads a PDF, andPOST .../reviewmarks the terms as checked, with corrections. The MCP server can read commitments, but it cannot read a PDF or review one. See Lender commitments. -
Value history of a deal's property.
GET /v1/deals/{id}/property-valuationslists each valuation of the property the deal's mortgage is on, newest first: the home value trend on the client's equity report. The MCP server has a tool for it. See Value history of the deal's property. -
Split mortgages. An opportunity returns
segments: the parts of a split mortgage, such as a fixed portion beside a line of credit, with each part's balance, rate, term and lender. Rates are percent.PATCH /v1/opportunities/{id}takessegmentsand replaces every segment. See Change what the report shows. -
Assistant instructions.
GET,POST /v1/agent-instructionsandGET,PATCH,DELETE /v1/agent-instructions/{id}read and write the standing instructions a broker gives their assistant, the same list as Assistant settings in BrokerPlus. Only an admin can write a brokerage instruction. The MCP server has a tool for each, except delete. See Assistant instructions. -
E-signing rules.
GET,POST /v1/signing-policiesandDELETE /v1/signing-policies/{id}read and set which connected e-signing provider a team's documents go out through: the default, and an exception per lender. A rule names the provider. The MCP server can list and set rules, but not delete one. See E-signing rules. -
The compliance program.
GET /v1/compliance/programreads the brokerage's compliance program, andPATCHchanges the facts about the brokerage that the borrower disclosure prints: whom it acts for, how many lenders it acted for last year, and whether it lends. The rest of the program changes only in BrokerPlus.GET /v1/compliance/trainings,GET /v1/compliance/retention-policies,GET /v1/compliance/verifier-policyandGET /v1/compliance/monitoring-alertsread the training records, how long records are kept, the document check, and the alerts that screening raised. The MCP server has a tool for each, except the alerts. See The compliance program. -
A deal's compliance package.
GET,POST,PATCH /v1/deals/{id}/compliance/packageread, make from a template, and change the one PDF that holds a deal's documents for a lender or an auditor.POST /v1/deals/{id}/compliance/package/buildbuilds it, and is refused while a required document is missing or left out.GET /v1/deals/{id}/compliance/package/downloadanswers a link to the PDF. The MCP server has a tool for each, except the download. See A deal's package. -
Compliance package templates.
GET,POST /v1/compliance/package-templatesandGET,PATCH,DELETE /v1/compliance/package-templates/{id}read and change the layouts that a deal's compliance package is built from: a team's own templates, and the brokerage's, which only a compliance administrator changes.GET /v1/compliance/package-requirementslists what a slot can hold. The MCP server has a tool for each, except delete. See Package templates. -
Evidence for a custom requirement. In
GET /v1/deals/{id}/compliance, each of thedocument_requirementsnow hascustom_obligation_idandevidence, the documents that answered it.POST /v1/deals/{id}/compliance/custom-obligations/{obligationId}/documentsuploads a file for a custom requirement, andDELETEon.../documents/{documentId}takes one off. The MCP server can upload, but it cannot take a document off. See Evidence for a custom requirement. -
Identity verifications.
GET /v1/deals/{id}/identity-verificationslists the identity verifications of the people on a deal, with the evidence each one examined. A document number shows only its last four characters, and the images and the reports are not published. The MCP server has no tool for it. See Identity verifications. -
Deal risk assessment.
GETandPATCH /v1/deals/{id}/risk-assessmentread and save the FINTRAC risk assessment of a deal: the transaction types, the fraud questions, the FINTRAC report, and the risk level. A save adds the answers you send to the answers on file. The MCP server has no tools for it. See Deal risk assessment. -
Know-your-client records.
GET /v1/deals/{id}/kyc-recordsandGET,PATCH /v1/deals/{id}/kyc-records/{contactId}read and save the FINTRAC information record of each party on a deal, as the KYC editor does.GET /v1/deals/{id}/entity-verificationsandGET,PATCH /v1/deals/{id}/entity-verifications/{contactId}do the same for the entity verification of a company. An imported ID number shows only its last four characters. The MCP server has no tools for these records. See Know-your-client records. -
The changes asked of a client.
GET /v1/intakes/{id}/change-requestslists every answer and file the broker asked a client to fix, with astatusfilter.PATCHrewords one,POST .../resolveandPOST .../reopenmark it done or open again, andDELETEwithdraws it. None of these sends anything. The MCP server has a tool for each, except delete. See Follow up on the changes you asked for. -
Strategy analyses.
GET,POST /v1/strategy-analysesandGET,PATCH,DELETE /v1/strategy-analyses/{id}read and write the strategy board's analyses: up to 8 mortgage options compared against one, with the client's plans and the note that explains the recommendation. Rates are percent. The MCP server has a tool for each, except delete. See Strategy analyses. -
Booked meetings are leads. A lead's
sourceand a contact'screated_viatake the new valuebooking: a person who booked a meeting through one of the broker's booking links. It fireslead.createdlike a form lead. A lead sent withPOST /v1/leadsnow also lands on the broker's Where New Leads Go column, the same as a form lead. -
Maturity date on the application.
PATCH /v1/deals/{id}/applicationtakesmaturity_date. This is the date that stage requirements check. Thematurity_dateonPATCH /v1/deals/{id}is a different field, and stage requirements do not read it. -
Ground rent and the condo fee. A subject property has
annual_ground_rent, the yearly ground rent on leasehold land. Whencondo_fee_tds_pctisnull, BrokerPlus counts all of the condo fee in the debt service ratios. Before this change, it counted half. -
Secured lines of credit. A liability has
secured_by_home,truewhen the broker marked a line of credit as secured against a home. The debt service ratios count such a line at the higher of its stated payment and its balance repaid over 25 years at the qualifying rate. -
How BrokerPlus calculates
gdsandtdschanged. These rules are new, and each one can changegdsandtdson a deal that already has them:- A subject property with no property tax is charged the tax bill on file, when one matches its address as the application holds it now. Otherwise it is charged 1% a year of the purchase price or the appraisal, whichever is lower.
- A subject property with no heating is charged the heating the client gave. Otherwise it is charged $100 a month, or $0.75 a square foot a year if that is higher.
- Every other property that counts in
tdsand has no property tax is charged 1% of its value a year. One with no heating is charged $100 a month. - Each rental property's rent is offset or added back by its own stated treatment and percent. Before this change, the first rental in the list set the treatment for all of them.
- An instalment or student loan that owes money and has no payment, or a $0 payment, is charged 3% of its balance a month.
- A credit card or an unsecured line of credit is charged the higher of its stated payment, 3% of the balance and $10.
- Child benefit counts as at most 30% of the qualifying income.
- Ground rent counts in full. A zero tax, heating or payment counts as blank in each of these rules.
2026-10-09
-
Files on snippets.
POST /v1/snippets/{id}/attachmentsadds a file to a snippet, andDELETE /v1/snippets/{id}/attachments/{attachmentId}removes one. The file's type is read from its content, and content with no recognisable type is taken only as CSV. The MCP server has a tool to add a file, but not to remove one. See Snippets. -
What the checks raised on an intake.
GET /v1/intakes/{id}/flagslists the flags BrokerPlus's checks raised on a client's intake, the most serious first, with astatusfilter.POST /v1/intakes/{id}/flags/{flagId}/overridesets one aside with the broker's reason, as Override does in BrokerPlus. The MCP server has a tool for both. See Review what the checks raised. -
Participant seats.
GET,POST,PATCH, andDELETEon/v1/participant-seatsread, add, pin, and remove the seats that a team's deals keep for a participant, with a default person for each.GET /v1/deals/{id}/participant-seatsshows which seats one deal has, andPOST /v1/deals/{id}/participant-seats/{seatId}/adoptand.../dismisschange that deal only. The MCP server has a tool for each read and for adopt and dismiss. See Participant seats. -
Offers and scenarios on a deal.
GET,POST /v1/deals/{id}/offersandGET,PATCH,DELETE /v1/deals/{id}/offers/{offerId}read and write the lender offers on a deal's offers tab, with their fees.GET /v1/deals/{id}/offers/compareis the tab's side-by-side comparison: payment, insurance, penalty, fees and APR for each offer, and each scenario priced at its rates./v1/deals/{id}/scenariosreads and writes the deal's what-if scenarios the same way. Rates are percent. The MCP server has a tool for each, except delete. See Offers and the comparison. -
Lead forms.
GET,POST,PATCH, andDELETEon/v1/lead-formsbuild, edit, and delete the forms a broker puts on a website, with the whole form inconfig, its page inurl, and how many leads it brought in.GET /v1/leadstakeslead_form_idto list one form's leads. A write cannot turn on a form's auto-reply:POST /v1/lead-forms/{id}/turn-on-auto-replyasks the broker, who approves it in BrokerPlus.GET /v1/approvalshas the new actionlead_form.auto_replyand the target typelead_form. The MCP server has a tool for each, except delete. See Lead forms. -
Who referred whom.
GET,POST /v1/contact-referralsandGET,PATCH,DELETE /v1/contact-referrals/{id}read and write the referral between two contacts: the person who sent a client to the broker, with its kind, status, note, and linked deal. The MCP server can list, read, record, and edit them. See Who referred whom. -
Stop automations messaging a client.
POST /v1/automations/stopsstops automations from messaging a client, for every deal or one, and for every kind of automation or some. It happens now.GET /v1/automations/stopslists the stops.POST /v1/automations/stops/{id}/liftasks the broker to lift one, with the new approval actionautomation_stop.lift, and the new approval target typeautomation_stop. The MCP server has a tool for each. See Stop automations messaging a client. -
Automation canvas groups.
GET,POST,PATCH, andDELETE /v1/automations/canvasesread and change the groups that automations are filed under on the automation canvas.POST /v1/automations/canvases/{id}/turn-offturns a group off now.POST /v1/automations/canvases/{id}/turn-onturns a group on: an automation that can message clients waits for the broker's approval, the same as one turned on by itself. The MCP server has a tool for each operation except the delete. See Group automations on the canvas. -
Call lists.
/v1/call-listsmakes, renames, and deletes the broker's call lists, from contacts, deals, or rows of names and numbers (POST /v1/call-lists/import)./v1/call-lists/{id}/entrieslists the people on a list, adds more, records each call's outcome and note, and takes a person off. Nothing is sent to anybody. The MCP server has a tool for each, except the deletes. See Call lists. -
Mentions, reactions, and files on notes. A deal note and a contact note now have
mentions,reactions, andattachments.GET /v1/deals/{id}/notes/mentionablelists who a note can mention.POST /v1/deals/{id}/notes/{noteId}/reactionsadds or takes off an emoji reaction.POST /v1/deals/{id}/notes/{noteId}/attachmentsattaches a PDF, andGET /v1/deals/{id}/notes/{noteId}/attachments/{attachmentId}gives a link to it. The same paths work under/v1/contacts. The MCP server has a tool for each, except the download link. See Mentions, reactions, and files. -
Debt consolidation analysis.
POST /v1/deals/{id}/consolidation-analysescompares paying out the client's debts with a refinance, a line of credit, or a reverse mortgage, the same as the Debts tab.GET /v1/deals/{id}/consolidation-analysesandGET /v1/deals/{id}/consolidation-analyses/{analysisId}read the saved analyses. A debt that you add or change through/v1/deals/{id}/liabilitiesnow takesdebt_type, which puts it in the analysis. The MCP server has a tool for each. See Debt consolidation analysis. -
Who a deal is waiting on.
GET /v1/work-watchesandGET /v1/work-watches/{id}read what each deal is waiting for, who owes the next move, since when, and how overdue it is: the waiting-on chips on a deal card. They are read-only. The MCP server has a tool for each. See Who a deal is waiting on. -
Notes on a document.
GETandPOSTon/v1/documents/{id}/notes, andPATCHandDELETEon/v1/documents/{id}/notes/{noteId}, read and write the notes brokers keep on one deal document. Only the author changes or deletes a note. The MCP server has a tool for each, except delete. See Notes on a document. -
PDFs in the client hub.
GET,POSTandDELETEon/v1/hub-resourceslist, add and remove the PDFs on the Resources tab of a client's hub, for every client or for one deal's client. The MCP server can list them. See PDFs in the client hub. -
The team's own document types.
GET,POSTandDELETEon/v1/custom-document-typesread, add and remove the documents a team asks for that BrokerPlus does not know, each with thecustom:code a document package names. Nothing reaches a client. The MCP server has a tool for each, except remove. See The team's own document types. -
Equity report send and open history.
GET /v1/equity-reports/sendslists each time a report went out to a client, with its channel, cadence, and whether it left BrokerPlus.GET /v1/equity-reports/interactionslists what clients did with their reports: opened the email, opened the report, asked for a call, or corrected a figure. Both takeupdated_sinceandafter_id. The MCP server has a tool for each. See Read the send and open history. -
Valuation history of an other property.
GET /v1/deals/{id}/other-properties/{propertyId}/valuationslists each valuation of the property, newest first, and the change in its estimate over the last year as a percent.POST /v1/deals/{id}/other-properties/{propertyId}/refresh-valuationasks for a new estimate in the background. The MCP server has a tool for each. See Valuation history of an other property. -
Call scripts.
GET,POST,PATCH, andDELETEon/v1/call-scriptsread, make, change, and retire the broker's own call scripts, the questions they read on a call. The MCP server has a tool for each, except retire. See Call scripts. -
Note types.
GET /v1/note-typeslists the kinds that a deal note or a contact note can have.POST /v1/note-types,PATCH /v1/note-types/{scope}/{slug}andDELETE /v1/note-types/{scope}/{slug}add, change and remove kinds for the broker's team.POST /v1/deals/{id}/notesandPOST /v1/contacts/{id}/notesaccepttype, so a new note can have a kind other thangeneral. The MCP server has a tool for each. See Note types. -
The broker's own rates.
GETandPOST /v1/me/rate-overridesread and set the rates a broker keeps on the Rates page, in percent.DELETE /v1/me/rate-overrides/{id}removes one, andPOST /v1/me/rate-overrides/resetgoes back to live rates.POST /v1/me/custom-lendersadds custom lenders with their rates, andPATCH /v1/me/custom-lenders/{lenderSlug}renames one./v1/me/lender-offsetsreads, sets, and removes per-lender offsets in basis points. The MCP server has a tool for each read and set. See Rates. -
Funding packages.
GET /v1/deals/{id}/funding-packagereturns the lender's funding forms that the broker is preparing on a deal. Add forms withPOST /v1/deals/{id}/funding-package/itemsorPOST /v1/deals/{id}/funding-package/upload, map their fields withPOST /v1/deals/{id}/funding-package/items/{item_id}/map, and set the signer, fields and state withPATCH /v1/deals/{id}/funding-package/items/{item_id}. The broker sends the package in BrokerPlus. The MCP server has a tool for the reads, the add, the map and the update. See Funding packages. -
Partner roles on a contact.
GET,POST /v1/contacts/{id}/partner-rolesandPATCH,DELETE /v1/contacts/{id}/partner-roles/{roleId}list, add, edit, and remove what a contact does for the broker's clients, such asrealtororlawyer, with a title, website, and booking link. The MCP server can list, add, and edit them. See Partner roles. -
Snippets.
GET /v1/snippetslists the saved replies of the broker your key acts as, andPOST,PATCHandDELETEon/v1/snippetsadd, edit and delete them, the same as the snippet manager in the inbox.GET /v1/snippets/{id}/attachments/{attachmentId}gives a link to a snippet's file. The MCP server can list, read, add and edit them. See Snippets. -
Mail folders.
GET /v1/communication-folderslists the folders and labels of a connected mailbox.POST /v1/communications/{id}/foldersfiles a whole conversation into a folder, andDELETE /v1/communications/{id}/folders/{folderId}takes it out; the move also happens in the broker's mail app. Each folder in a communication'sfoldersnow has itsid. The MCP server has a tool for each, except taking a conversation out. See File a conversation in a folder. -
Inbox tags.
GET /v1/communication-tagslists the brokerage's inbox tags, andPOST,PATCHandDELETEon/v1/communication-tagsadd, rename and archive them.POST /v1/communications/{id}/tagsputs a tag on a whole conversation, andDELETE /v1/communications/{id}/tags/{tagId}takes it off. A communication now lists its tags intags, each with itsid,nameandcolor. The MCP server has a tool for each, except taking a tag off and archiving one. See Tag a conversation. -
Mortgage plans.
GET /v1/mortgage-plans,GET /v1/mortgage-plans/{id},POST /v1/mortgage-plans,PATCH /v1/mortgage-plans/{id}, andDELETE /v1/mortgage-plans/{id}read and build the plans from the plan builder, on a deal or a contact. Rates are percent. The MCP server has a tool for each, except delete. See Plans and comparisons. -
Team note.
GET /v1/teams/{id}/notereads the note that a team's members share on their overview, andPATCH /v1/teams/{id}/notereplaces it. Only a member of the team can reach it. The MCP server has a tool for each. See Team note. -
Document packages.
GET,POST,PATCHandDELETEon/v1/doc-packagesread and change the named sets of documents that the broker's team asks for together.GET /v1/doc-packages/sampleslists the situations BrokerPlus recognizes, andPOST /v1/doc-packages/samples/{key}adds one as a package.GET /v1/doc-packages/{id}reads one. Nothing reaches a client. The MCP server has a tool for each, except delete. See Document packages. -
The client tracker.
/v1/tracker-stageslists, adds, changes, reorders, and removes the stages a client sees on their hub, and sets the note from the broker.GET /v1/deals/{id}/trackershows one deal's tracker as the client sees it.POST /v1/deals/{id}/tracker/{stageId}/reachreturns a pendingtracker.reachapproval: the client sees the stage only when the broker approves.POST /v1/deals/{id}/tracker/{stageId}/retracttakes stages back down at once. The MCP server can read the tracker and ask to reach a stage. See Client tracker. -
What a client was asked for, item by item.
GET /v1/intakes/{id}/itemslists each document, form, consent and identity check on the client's portal, with each applicant's state and the files they sent.GET /v1/intakes/{id}/uploadsandGET /v1/intakes/{id}/uploads/{uploadId}read the files.POST /v1/intakes/{id}/uploads/{uploadId}/stageandPOST /v1/intakes/{id}/items/{key}/stageaccept a file or an item, as a move on the document board does.POST /v1/intakes/{id}/request-changesnow takesuploadsto refuse a file and ask the client for a new copy, andchangesis optional. See Read what the client was asked for. -
Request templates.
GET /v1/request-templateslists the broker's request library, andGET /v1/request-templates/{id}reads one template with its items. You can create, change, copy, star, reset and delete a template, and add, change, order, reset and remove its items. Building a template sends nothing. The MCP server has a tool for each, except the two deletes. See Request templates. -
Ask for documents from a template.
POST /v1/deals/{id}/document-requestsacceptstemplate_id, and asks for the documents on that request template.documentsis now optional when you sendtemplate_id. See Ask from a request template. -
The brokerage's rates.
/v1/brokerage/rate-overridesand/v1/brokerage/lender-offsetsread, set, and remove the rates and offsets a brokerage sets for every broker, in percent and basis points.POST /v1/brokerage/rate-overrides/resetgoes back to live rates. Only a brokerage admin's key can call them. The MCP server has a tool for each read and set. See The brokerage's rates. -
Lender cashback.
GET /v1/lender-cashbacklists the cashback each lender pays, in percent, as the opportunity figures use it.POST /v1/lender-cashbackandDELETE /v1/lender-cashback/{lenderSlug}set and remove the brokerage's own, with a brokerage admin's key. The MCP server has a tool to read and to set. See Lender cashback. -
Rate sheets.
POST /v1/rate-sheetsuploads a lender's rate sheet and answers with the rates BrokerPlus read from it, in percent, and the cells they fit.POST /v1/rate-sheets/{id}/applyputs the rows you choose on the broker's own rates.GETlists and reads sheets, andDELETEremoves one. The MCP server has a tool for each, except delete. See Rate sheets. -
Partner hub links.
POST /v1/partner-hubsopens a referral partner's hub and issues a link that the partner opens to see every file they are on with the broker.POST /v1/partner-hubs/{id}/linkissues another link to a hub.GET /v1/partner-hubsandGET /v1/partner-hubs/{id}list the hubs and their working links. BrokerPlus sends nothing: you give the link to the partner. The MCP server has a tool for each. See Partner hub links. -
NPS alert rules.
GET,POST,PATCH, andDELETEon/v1/nps-alert-rulesread and change the rules that alert brokers and add a task when a client answers a survey. The MCP server has a tool for each, except delete. See NPS alert rules. -
NPS surveys.
GET /v1/nps-surveysandGET /v1/nps-surveys/{id}read the surveys sent to clients, with each score, its band, and the comment.POST /v1/nps-surveysasks the broker to email a client the survey; it waits for the broker's approval, under the new approval actionnps.send. The MCP server has a tool for each. See Ask a client for a score. -
Choose the finished files on a partner hub. A partner hub has
show_fundedandshow_not_proceeding. They choose if the hub lists the files that funded and the files that ended without funding. Both aretrueby default.POST /v1/partner-hubsaccepts either one.
2026-10-08
-
Record a funding date on a closed deal.
PATCH /v1/deals/{id}acceptsfunded_aton a deal that is alreadyclosed. The status staysclosed. An imported file that its source system marked funded takes the date as is. On any other closed deal, the date counts the deal as funded, so it needs the same anti-money laundering (AML) clearance as a change tofunded. You can't close a deal and date it in one request. -
Write accelerated payments.
PATCH /v1/deals/{id}/applicationnow acceptspayment_accelerated:true,false, ornull. Pair it withpayment_frequency: 26for bi-weekly or52for weekly. -
Invalid numeric codes name the choices. Validation errors now list each accepted code and label. The API reference also lists the accepted numeric codes. See Units and formats.
-
You can cancel an approval you asked for.
POST /v1/approvals/{id}/cancelwithdraws apendingapproval before the broker answers. It becomesrejectedwith the reasonCancelled by the requester.Only the key that asked can cancel it. -
Asking twice files one approval. A repeat of a request that is still
pending(same action, record, recipients, sender and words, from the same person) returns the existing approval instead of a second card for the broker. -
An approval whose record is deleted is voided. Deleting the campaign, appointment, automation, automation run or deal an approval is about now voids it at once, with
"changed": ["missing"], instead of leaving itpending. -
Registering the same webhook twice is refused.
POST /v1/webhookswith a URL and events you already registered returns409WEBHOOK_EXISTS, with the existing endpoint indetails.webhook_id. The same URL for different events, or another broker's endpoint on it, is still allowed. -
Every authenticated response carries
Cache-Control: no-store, so no proxy or HTTP cache keeps a broker's data. -
The MCP server refuses an argument a tool does not take. It used to drop it, so a misspelled filter returned every row. The error names the argument and lists the ones the tool takes.
-
An unknown filter value is refused.
statuson deals and on a deal's conditions,typeon automations, andinclude_archivedon templates now return400VALIDATION_ERRORwith the values they take. A value such asstatus=BOGUSused to return an empty page. The filters on approvals, automation runs, custom fields, andarchive_dealson a pipeline delete now name the parameter indetails.fieldErrorstoo. -
after_idworks on every list that documents it. Templates, automations, meeting types, a deal's documents, and a deal's terms history now resume a sync after the row you name, and return400VALIDATION_ERRORwhenafter_idcomes withoutupdated_since. They used to ignore it.GET /v1/contacts/duplicatesrefusesafter_id, because a set has no position to resume after. -
Fixed: an equity report's
ltvcould read 100 times too high. Some reports returned5170where the loan-to-value was51.7. Every report now returns itsltvas a percent. -
A control character in a query value is refused. A NUL or another control character in any query parameter, such as
lender_file_ref=%00, now returns400VALIDATION_ERRORnaming the parameter. It used to return500. Tabs and line breaks are still accepted. -
A
pageout of range is refused. Every list takespagefrom1to1000000. A largerpage, or apageorpage_sizethat is not a whole number, now returns400VALIDATION_ERRORnaming the parameter. A very largepageused to return500, and apagesuch asabcwas read as page1. See Pagination. -
A date that does not exist is refused.
updated_since,fromandtoon availability, and a report'sstartandendnow return400VALIDATION_ERRORfor a date such as2026-02-30or a time such as24:00. These used to be read as the next real date, soupdated_since=2026-02-30T00:00:00Zquietly meant March 2. -
GET /v1/changesrefuses a checkpoint sent with moretypesthan it was issued for. A checkpoint moves past every entry its owntypescovered, so reading more types from it skipped their entries without a word. It now returns400 INVALID_CHECKPOINT. The sametypes, or fewer, still work. A checkpoint fromafter=nowbelongs to thetypessent with it, or to every type when none were sent. Atypesvalue that names no type, such as,,,, now returns400instead of500, and so does a malformed checkpoint. See Sync. -
Breaking: a referral partner's
conversion_rateis now a percent. It was a decimal fraction, such as0.25. It is now25, like every other rate. This is onGET /v1/referral-partnersandGET /v1/referral-partners/{id}. See Units and formats.
2026-10-07
Summary: the API grew to about 300 operations, with three breaking changes.
If you built on the API before today, check these three first:
- Rates on an opportunity, and the
ltvon an equity report, are now percents.target_new_rate,breakeven_rate, andltvwere decimal fractions, such as0.0499. They are now4.99. Remove any step that multiplies them by 100. See Units and formats. - Booking, moving, or cancelling a meeting, asking for intake changes, and emailing an intake now
wait for the broker's approval.
POST /v1/appointments/book,.../reschedule,.../cancel, andPOST /v1/intakes/{id}/request-changesreturn202and a pending approval instead of acting at once.POST /v1/intakeswithdelivery: "email"still returns201, with anapproval_id, and emails nobody until the broker approves. See Approvals. - The action on many tasks moved to
POST /v1/tasks/bulk.POST /v1/tasks/batchnow creates or updates tasks, like the other batch endpoints.
What is new, in short: batch writes for contacts, leads, deals, and tasks; the mortgage application one row at a time; document uploads, requests, generated letters, and signing; workspace setup (custom fields, tags, pipelines, lead stages, task categories, meeting types, hours); automations and templates; equity report enrollment; the call log; suggestions, notifications, compliance and credit reads, and activity trails; sandboxes; key limits; and sign-in for MCP connectors. The entries below have the detail.
These docs were reorganized around the same release: a home page by job, one Concepts section, and the old Claude command center page merged into Run an AI assistant. Old links still work.
Added: flags on a deal.
GET /v1/deals/{id}/flagslists the flags that are up on a deal, with each reason in plain words.POST /v1/deals/{id}/flagsraises the broker's flag, andPOST /v1/deals/{id}/flags/{flagId}/cleartakes it down. A flag from an automation or from BrokerPlus is read-only. Refer to Flags.
Changed: an approval task cannot be cancelled or reopened with the API.
POST /v1/tasks/{id}/cancelandPOST /v1/tasks/{id}/reopennow answer409withAPPROVAL_TASKfor an approval task, asPOST /v1/tasks/{id}/completealready did. Only the broker decides an approval, in BrokerPlus.
Added: read and set the checklist on a deal.
GET /v1/deals/{id}/checkpointslists the steps of the checklist and their values on the deal.PATCH /v1/deals/{id}/checkpoints/{checkpointId}sets one step. Refer to The deal's checklist.
Changed: the action on many tasks moved to POST /v1/tasks/bulk.
- It was at
POST /v1/tasks/batchfor a few hours today.POST /v1/tasks/batchnow creates or updates tasks, as it does for contacts, leads, and deals.
Added: copy a deal, and restore an archived one.
POST /v1/deals/{id}/duplicatemakes a new deal with the same people.POST /v1/deals/{id}/restoreputs an archived deal back on its pipeline. Refer to Copy, archive, and restore a deal.
Added: batch writes for contacts, leads, deals, and tasks.
POST /v1/contacts/batch,POST /v1/leads/batch,POST /v1/deals/batch, andPOST /v1/tasks/batchcreate or update up to 100 records in one request. Refer to Migrate from another CRM.- Send
external_idwithnamespace, and a later batch with the same id updates the same record. - An item that fails does not stop the other items. Each item counts as one request against the rate limit.
- The MCP server does not have batch tools. An assistant writes one record at a time.
Added: complete, cancel, or reopen many tasks at once.
POST /v1/tasks/bulkapplies one action to up to 200 tasks and lists the tasks it changed and skipped. Refer to Tasks.
Added: the call log, and calls from other phone systems.
POST /v1/callsputs a call from another phone system or recorder in the call log of the broker, with its transcript. The call shows on the contact and the deal. Refer to Log calls from your phone system.GET /v1/callsandGET /v1/calls/{id}read the call log, with each transcript and recap.- The
call.loggedwebhook event fires when a call lands in the call log. - The MCP server has the
brokerplus_log_call,brokerplus_list_calls, andbrokerplus_get_calltools.
Added: send documents to sign.
GET /v1/deals/{id}/signing-documentsandGET /v1/deals/{id}/signing-documents/{documentId}read a deal's signing package, with where each signing is instatus.GET /v1/deals/{id}/signing-presetslists the presets for a deal, andPOST /v1/deals/{id}/signing-documentsadds a saved document, or each one in a preset, for the person who signs it.POST /v1/deals/{id}/signing-documents/{documentId}/previewreturns the document filled in, as a PDF.POST /v1/deals/{id}/signing-documents/sendreturns a pending approval with the new actionsigning.send. When the broker approves, each document is filled in and checked again, and each signer gets one email.POST /v1/deals/{id}/signing-documents/{documentId}/resendreturns a pending approval with the new actionsigning.resend. A key with theno_sendinglimit cannot send or resend. Refer to Ask a client for something.
Added: change, copy, pause, and delete campaigns and audiences.
PATCH /v1/campaigns/{id}changes a draft.POST /v1/campaigns/{id}/duplicatecopies a campaign as a new draft.POST /v1/campaigns/{id}/pausestops a campaign that is sending.DELETE /v1/campaigns/{id}deletes a campaign.PATCH /v1/audiences/{id}andDELETE /v1/audiences/{id}change and delete an audience. Refer to Approvals.
Added: act on a conversation in the inbox.
PATCH /v1/communications/{id}marks a conversation read or unread, marks it done, stars it, sets or clears a reminder, and files its mail on a deal. Refer to Mail.
Added: ask a client for documents, and explain conditions to the people on a deal.
POST /v1/deals/{id}/document-requestsasks the client for documents, as the Request Documents window does. It returns202and a pending approval with the new actiondocument_request.send. When the broker approves, the documents are added to the client's portal and each applicant gets an email.POST /v1/deals/{id}/condition-requestswrites the letter that explains conditions in plain language, files it as the broker's draft, and returns202and a pendingmessage.sendapproval.- A key with the
no_sendinglimit cannot make these requests. Refer to Ask a client for something.
Added: generated documents.
GET /v1/document-templateslists the document templates the key's user can use, for example an approval letter.POST /v1/deals/{id}/generated-documentsmakes a document from a template and files the PDF on the deal. If the broker must fix something first, the document stays adraftandissuessays what.GET /v1/deals/{id}/generated-documentsandGET /v1/deals/{id}/generated-documents/{documentId}read them.POST /v1/deals/{id}/generated-documents/{documentId}/sendfiles an email to one person on the deal with the PDF attached, and returns202and a pendingmessage.sendapproval. A key with theno_sendinglimit cannot send one, and a key with theno_documentslimit cannot use any of these.
Added: rename, refile, verify, and delete documents.
PATCH /v1/documents/{id}changesdisplay_name,contact_id, andexcluded_from_submission.POST /v1/documents/{id}/stagemoves a document betweenpending,review, andverified, and files a verified document in afolder.DELETE /v1/documents/{id}deletes a document. Refer to Files.
Added: change the tags, lead stages, lead channels, and referral partners of a brokerage.
POST /v1/contact-tagsandPOST /v1/deal-tagscreate a tag.PATCHchanges its name or colour, andDELETEarchives it and takes it off every record.POST /v1/lead-stagescreates a column on the Leads board,PATCHrenames it, andPOST /v1/lead-stages/reordersets the order.DELETE /v1/lead-stages/{id}moves the stage's leads tomove_to, or to the first stage that stays.POST,PATCH, andDELETEon/v1/lead-channelscreate, change, and archive a lead channel.POST /v1/referral-sourcescreates a referral partner and its partner contact.PATCHchanges it, andDELETEarchives it.GET /v1/lead-stagesandGET /v1/lead-channelsnow return the default stages and channels to a brokerage that did not open the Leads board yet.- A key with the
leads_onlylimit cannot change the lead stages, lead channels, or referral partners. Refer to Configure your workspace.
Added: suggestions, notifications, compliance checklists, credit reports, and activity trails.
GET /v1/suggestionslists the changes that BrokerPlus suggests to the broker.POST /v1/suggestions/{id}/approvecarries out a suggestion that stays inside BrokerPlus, andPOST /v1/suggestions/{id}/dismissturns one down. A suggestion that reaches a client returns409 APPROVE_IN_BROKERPLUS: the broker approves it in BrokerPlus. Refer to Suggestions, notifications, and deal checks.GET /v1/notificationslists the notifications of the broker that your key acts as.POST /v1/notifications/{id}/readandPOST /v1/notifications/read-allmark them read.GET /v1/deals/{id}/compliancereturns the compliance checklist of the deal: the checkpoints, the open items, the identity and know-your-client checks on each party, the consents, the suitability answers, and the required documents. It does not contain ID numbers, ID images, or dates of birth.GET /v1/deals/{id}/credit-reportsreturns the score, the bureau, the report date, and the account totals of each credit report. It does not contain the report or the account numbers. The API cannot pull credit.GET /v1/deals/{id}/activityandGET /v1/contacts/{id}/activityreturn the activity trail: messages, calls, notes, and changes to the deal.- The MCP server has tools for suggestions, notifications, and activity trails.
Added: change meeting types, the broker's hours, blocked days, and the email signature.
POST /v1/meeting-typescreates a meeting type.PATCH /v1/meeting-types/{id}changes its length, hours, buffers, notice, questions, form fields, and reminders.DELETE /v1/meeting-types/{id}deletes it.POST /v1/meeting-types/reordersets their order.GET /v1/me/hoursandPATCH /v1/me/hoursread and change the time zone, phone hours, and booking hours of the key's broker.GET /v1/me/blocked-days,POST /v1/me/blocked-days, andDELETE /v1/me/blocked-days/{date}list, block, and unblock the days when clients cannot book the broker.GET /v1/me/email-signatureandPATCH /v1/me/email-signatureread and change the broker's email signature.- A key changes only its own broker's hours and signature. Refer to Configure your workspace.
Added: edit, pin, and delete notes.
PATCH /v1/contacts/{id}/notes/{noteId}andPATCH /v1/deals/{id}/notes/{noteId}change the words, the pin, or the kind of a note.DELETE /v1/contacts/{id}/notes/{noteId}andDELETE /v1/deals/{id}/notes/{noteId}delete a note and its replies.PATCH /v1/tasks/{id}/notes/{noteId}changes the words or the pin of a task note.DELETE /v1/tasks/{id}/notes/{noteId}deletes a task note that you wrote.
Added: change the task categories of a team.
POST /v1/task-categoriescreates a category,PATCH /v1/task-categories/{id}renames it, andDELETE /v1/task-categories/{id}deletes it. Its tasks go back to their built-in category.POST /v1/task-categories/hiddenhides built-in categories from the team.GET /v1/task-categoriesnow returnshiddenon each category.- Only the team's broker or a brokerage admin can make these changes. Refer to Configure your workspace.
Added: change the pipelines and stages of a team.
POST /v1/pipelinescreates a pipeline.PATCH /v1/pipelines/{id}changes it,POST /v1/pipelines/reordersets the order, andDELETE /v1/pipelines/{id}deletes it. A pipeline that has deals is deleted only witharchive_deals=true.POST /v1/pipelines/{id}/stages,PATCH /v1/pipelines/{id}/stages/{stage_id},POST /v1/pipelines/{id}/stages/reorder, andDELETE /v1/pipelines/{id}/stages/{stage_id}add, change, order, and archive its stages.- Each stage returns
requirements: what a deal must have before it can move into the stage. You can set them on a create or an update. Refer to Configure your workspace.
Added: change the custom fields of a brokerage.
POST /v1/custom-fieldscreates a contact or deal field.PATCH /v1/custom-fields/{id}changes its label, options, group, or default.DELETE /v1/custom-fields/{id}archives it, and BrokerPlus keeps its answers.POST /v1/custom-fields/reordersets the order of the fields.- Only a key that belongs to a brokerage admin can make these changes. Refer to Configure your workspace.
Added: a common-law relationship type.
GET /v1/contacts/{id}/relationshipscan returncommon_lawas atype. It reads the same from both contacts.
Added: equity report enrollment, and opportunities you add by hand.
POST /v1/equity-reports/enrollasks the broker to start a client's recurring equity reports.POST /v1/equity-reports/resumeasks to restart paused ones.POST /v1/equity-reports/sendasks to send one report now, by email or SMS. Each returns202with a pending approval and a line for each deal. Nothing starts or goes out until the broker approves it in BrokerPlus. Refer to Equity reports.POST /v1/equity-reports/pause,POST /v1/equity-reports/unenroll, andPOST /v1/equity-reports/frequencypause reports, stop them, or change how often they go out. They happen immediately.- A client who opted out of reports, or is under a sanctions freeze, is refused for each deal, the same as in BrokerPlus.
POST /v1/opportunitiesadds a mortgage to the book, the same as Add Client in BrokerPlus.PATCH /v1/opportunities/{id}takesname.GET /v1/opportunitiestakesmonthly_reports_enabled.- An approval can have the action
equity_report.enroll,equity_report.resume, orequity_report.send, and the target typedeal.
Added: build and run the same automations as the Pulse builder.
GET /v1/automations/cataloglists every trigger type and itsconfig, every step kind and itsparams, who a message can go to, the fields a check can compare, and the node kinds of a graph.POST /v1/automationsandPATCH /v1/automations/{id}take any triggertypewithconfig,filters,repeat_policy,anchor_offset_days, andcanvas_id, and any stepkindwithparamsandonly_if. Sendgraphfor an automation with branches and waits. The older body (stage_id, and steps withchannelandtemplate_id) still works.POST /v1/automations/{id}/turn-onturns an automation on. When it can message clients, the response is202and an approval with the new actionautomation.turn_on, bound to the automation as it is written. A change before the broker decides voids it.POST /v1/automations/{id}/turn-offturns it off now.POST /v1/automations/{id}/duplicatemakes a copy, OFF.DELETE /v1/automations/{id}turns an automation off and removes it from the board.- Each automation returns
can_message_clientsandgraph. GET /v1/automation-runstakesdeal_idandcontact_id.- A refused automation returns
details.fieldErrorswith the field at fault, for examplesteps.1.params.templateId, and a message that says how to fix it.
Changed: what turns an automation OFF.
- A
PATCHthat changes onlyname,description, orcanvas_idnow leaves the automation on or off. Before, every change turned it OFF. A change to what the automation does still turns it OFF. - A step
kindother thanemailorsms, and a trigger other thanstage.transitioned, no longer return409 UNSUPPORTED_STEPSor409 UNSUPPORTED_AUTOMATION.
Added: who recorded a contact relationship, and when it last changed.
GET /v1/contacts/{id}/relationshipsreturnscreated_by_user_idandupdated_aton each relationship.
Added: more fields on keys, brokers, teams, webhooks, automations, templates, meeting types, appointments, mail, drafts, campaigns, and intakes.
GET /v1/mereturnsapi_key.created_at.GET /v1/organizationreturnshas_book_of_business.GET /v1/usersreturnstimezoneandlicense_numberfor each broker.GET /v1/teams/{id}/membersreturnscreated_atandupdated_atfor each seat.GET /v1/webhooksreturnsfailure_count, the events in a row that failed, andupdated_at.GET /v1/automationsreturnssort_orderandanchor_offset_days, andcreated_atandupdated_aton each step.GET /v1/templatesreturnsattachments: the name, size, and type of each file that goes with an email.GET /v1/meeting-typesreturnsbuffer_before_minutes,buffer_after_minutes,slot_interval_minutes,availability_hours,required_license_class,required_province,reminder_minutes,reminder_channels, andposition.GET /v1/appointmentsreturnsical_uidandshows_as_free.GET /v1/communicationsreturnsto_contact_ids,mailbox_user_id,done_at, andremind_at.GET /v1/draftsreturnsbody_html,reviewed_by_user_id, andrejection_reason.GET /v1/campaignsreturnsseries_id,follow_up_root_id,follow_up_step,follow_up_audience,started_at,paused_at,auto_paused_reason, andfailure_reason. Each recipient hasupdated_at.GET /v1/intakesreturnsportal_type,broker_user_id,template_id,application_id,status_note,status_note_updated_at,needs_changes_at,last_reminder_at, andreminder_count.
Added: sandboxes for testing.
- An admin can create a sandbox in Settings > Developer. A sandbox is a private brokerage with sample data. It records email, text messages, credit requests, and lender submissions, and it does not send them. Refer to Test in a sandbox.
- A sandbox key starts with
bp_test_. A sandbox key cannot get data from a live brokerage, and a live key cannot get data from a sandbox. GET /v1/sandbox/outboxlists what a sandbox recorded. Only a sandbox key can use it.
Added: more of what a broker sees on deals, opportunities, submissions, lenders, pipelines and commission.
- A deal has
stage_entered_at,application_date,archived_at,opportunity_type,origin,spawned_from_deal_id,realtor_contact_id,primary_application_id,submitting_broker_id, andchannel_id. Each entry inexternal_referenceshasurl,remote_status,remote_status_at,last_pulled_at, andcreated_at. - An opportunity has
name,comparison_rate,collateral_charge,cashback_enabled,cashback_override,best_option_pin,dismissed_by_user_id,last_client_contact_at,client_perceived_value,client_perceived_value_at, the property details (property_bedrooms,property_bathrooms,property_sqft,property_year_built,property_type), the report dates,outreach_blocked_at, andreport_frequency. Rates are in percent. PATCH /v1/opportunities/{id}also takescomparison_rate,collateral_charge,cashback_enabled,cashback_override, and the five property details. A value you send replaces the figure BrokerPlus has.- A submission has
cover_note,penalty_capitalized,simulated,validated_at, and, on a Finmo submission,goal,approval_type,gds,tds, andltvin percent. Asimulatedsubmission never reached a lender. - A lender has
contact_email,contact_phone,equifax_accredited,transunion_accredited,cmhc_approved,under_maintenance, andlending_guidelines. - A pipeline has
keyandbroker_user_id. A stage hasdescription,exclude_from_book,stops_automated_outreach,created_at, andupdated_at. - A commission has
created_by_user_id. Its line items havecreated_atandupdated_at, and its splits havecreated_at.
Changed: an intake that BrokerPlus emails now needs the broker's approval.
POST /v1/intakeswithdeliveryemailstill creates the intake and returns201, but nobody is emailed until the broker approves it in BrokerPlus. The response has a new field,approval_id. Read the approval withGET /v1/approvals/{id}. Fordeliverylink,approval_idis null and nothing changes.
Added: apps connect to the MCP server by signing in.
- Claude on the web, ChatGPT, and other connectors sign in with OAuth 2.1 and need no API key. The
401from the MCP server names the protected resource metadata, and that names the authorization server. Refer to MCP server. - The broker picks the team and whether the app may only read. The token resolves to the same authority as an API key with the same team and read only choice.
- A connection is listed with the API keys in Settings > Developer, and revoking it there disconnects the app. API keys work as before.
Changed: MCP tool results are structured.
- Each MCP tool declares an
outputSchema. The schema is the response schema of its endpoint, withoutsuccess. - Each tool result has
structuredContent: thedataof the response, and thepaginationof a list. - The text of a result starts with one line that names what came back, by name and id. The JSON of the result follows it.
- The MCP server adds
brokerplus_search_operations,brokerplus_describe_operation, andbrokerplus_call_operation. They find, describe, and call each API operation that the server publishes. Refer to MCP server. - The MCP server sends
401when the API refuses the key. Before, the first tool call failed instead. - The MCP server does not show write tools to a read-only key.
Changed: booking, moving, and canceling a meeting, and asking for intake changes, now need the broker's approval. This is a breaking change.
POST /v1/appointments/book,POST /v1/appointments/{id}/reschedule,POST /v1/appointments/{id}/cancel, andPOST /v1/intakes/{id}/request-changesnow return202and a pending approval. Before, they returned201or200and emailed the client immediately. Nothing changes and nobody is emailed until the broker approves the request in BrokerPlus. Refer to Messaging and approvals.- A booking approval expires at
start_at, or after seven days if that is sooner. If the time is taken before the broker approves, the approval isfailedand nothing is sent. - A second cancel of a canceled booking now returns
409 BOOKING_CANCELED. GET /v1/appointments/{id}/bookingreads the booking on an appointment, including after a move or a cancellation.
Changed: the ltv on an equity report is a percent.
ltvonGET /v1/equity-reportswas a decimal fraction, such as0.488. It is now a percent, such as48.8, the same unit as every other rate and ratio in the API. If you divide it by 100 or show it as a fraction, change that code.
Added: how an equity report reached the client.
- Each equity report has
channel:emailorsms.
Added: the record type, and names beside ids.
-
Every record now has an
objectfield that names its type, for example"deal","contact", or"task". It is always present and never changes for a type. Contact methods, relationships, approvals, and automation runs have it too. -
A deal adds
board_name,assigned_broker_name,underwriter_name, andlender_name. -
A task adds
deal_name,contact_name, andassignee_name. -
A contact adds
owner_name. A note on a deal or a contact addsauthor_name. -
An appointment adds
owner_nameanddeal_name. A draft addssender_name. -
A submission adds
submitted_by_name, andlender_namenow has a value on a BrokerPlus submission. -
No field changed its name or its type. Each name is for display: keep the id as your reference. Added: more of what a broker sees on contacts, tasks, conditions, and their lists.
-
A contact has
nickname,date_of_birth,phone_extension,language,assigned_broker_id,not_a_borrower,is_entity,opt_out_milestones,created_via, andarchived_at.GET /contacts/{id}returns an archived contact;GET /contactsstill leaves it out.POST /contactsandPATCH /contacts/{id}takenickname,date_of_birth, andphone_extension, andPATCHalso takeslanguage. -
A task has
parent_task_id,provenance,progress,snoozed_until, andcompleted_by_user_id.PATCH /tasks/{id}takesprogressandsnoozed_until. -
A condition has
lender_condition_name,plain_title,plain_description,tags,needs_review,status_note,status_note_at,resolved_at,satisfied_by_user_id,auto_satisfied_document_id, andsource_communication_id.PATCH /conditions/{id}takesstatus_note. -
A document has
excluded_from_submission. -
A lead has
lead_form_idandlead_form_name. -
A note on a deal or a contact has
type, the kind of note the brokerage filed it as. -
A tag has
is_typeandupdated_at. -
A consent has
text,text_version,locale,created_at, andupdated_at. -
GET /referral-sourcesreturnstype,company,contact_id,contact_details,notes,last_contact_at, andnext_follow_up_atfor each partner. -
GET /custom-fieldsreturnsid,default_value,position,created_at, andupdated_at. -
GET /task-categoriesreturnsid,position,created_at, andupdated_aton a custom category. -
A referral source, a custom field, and a task category have
object:"referral_source","custom_field_definition", and"task_category".
Added: the rest of the mortgage application.
GET /v1/deals/{id}/applicationreturnslabel,loan_type,charge_type,repayment_type,requested_payment,down_payment_override,legal_and_closing_costs,type_of_buyer,loan_purpose_additional,mortgage_classification,product_code,rate_compound_frequency,lender_classification,early_payout_type,capitalize_payout_penalty,purchase_stage,purchase_timeline,improvement_description, andsecurity_deposit_amount.PATCHchanges each of them exceptproduct_code.GET /v1/deals/{id}/propertyreturns the heating, water, parking, zoning, construction and description types,tenure, the property and lot size with their units,environmental_hazard,new_property,mls_listed, the rental and condo fee rules,annual_tax_estimated,tax_year,taxes_paid_by, the original purchase price and date, seven monthly operating costs,legal_description, andlegal_pin.PATCHchanges each of them excepttenure.- An applicant returns
honorific,suffix,sex, andcorrespondence_language. A job returnsindustry_varies,business_type, the employer's address and phone number, andamount_basison each income line. - An asset returns
applied_to_down_payment. A liability returnsdebt_type,description,original_loan_amount,closing_date,charge_type,repayment_type,redemption_status,rate_type,payoff_type,source_deal_id, andproperty_id. An other property returnsstreet_type,street_direction,value_estimate,value_source, the condo fee rules,mortgage_rate_type,mortgage_payment_frequency,rental_calc_type, and its monthly operating costs. - The row endpoints accept the new fields that a broker can edit. Refer to Applicants and financials.
Changed: webhooks for brokerages with more than one team.
- A brokerage with more than one team can now register and enable webhooks. The API does not
return
409 MULTI_TEAM_UNAVAILABLEfor webhooks. - An endpoint receives an event only when the key that registered it can read the record of that
event now, with the same rules as
GET /v1/changes. This is also true for a brokerage with one team. For example, anemail.receivedevent from a mailbox that the broker cannot see does not go to the endpoint. Refer to Who receives an event. - When the broker is deactivated or leaves the team of the key, the endpoint stops receiving events.
- An endpoint belongs to the broker whose key registered it. A key of a different broker gets
404for it, andGET /v1/webhooksdoes not show it. - The limits on a key apply to webhooks. A key with
no_documentsgets403 KEY_LIMITEDwhen it subscribes to a document event, and its endpoint never receives one. Refer to Who receives an event.
Added: limits on a key.
- A key can now have the limits
leads_only,no_sending, andno_documents, in addition toread_only. Set them when you create the key in Settings > API keys. Each limit removes access, and no limit can give a key more than its broker has. Refer to Limits on a key. - A request that a limit refuses returns
403 KEY_LIMITED, with the limit indetails.limit. GET /v1/mereports the limits of the key inapi_key.limits.
Changed: scheduling a campaign now needs the broker's approval. This is a breaking change.
POST /v1/campaigns/{id}/schedulenow returns202and a pending approval. Before, it returned200and scheduled the campaign immediately. The campaign stays a draft until the broker approves the request in BrokerPlus. The response still carrieswarnings.- The approval is bound to the campaign's words and its audience. A change to either one voids it.
It expires at
scheduled_at.
Added: messages and approvals. See Messaging and approvals.
POST /v1/contacts/{id}/messagesasks the broker to send one email or SMS to a contact.POST /v1/drafts/{id}/sendasks the broker to send a draft that waits for review.GET /v1/approvalsandGET /v1/approvals/{id}read each request and the broker's decision.GET /v1/automation-runs,GET /v1/automation-runs/{id}, andPOST /v1/automation-runs/{id}/startread automation runs and ask to start one now.POST /v1/automation-runs/{id}/cancelstops a run that has not started.- New webhook events:
approval.approvedandapproval.rejected. PATCH /v1/tasks/{id}andPOST /v1/tasks/{id}/completereturn409 APPROVAL_TASKfor an approval task.- The MCP server exposes all of these except approval. Only a broker can approve.
Added: who a deal's mail goes out as.
GET /v1/deals/{id}/senderreturns the broker whose name the client sees, the mailbox the mail leaves from, the team brand, and the business name in the footer. BrokerPlus finds it the same way a send finds it, from the deal's assigned broker. Refer to Automations.- The API cannot set the sender. To change it, assign another broker to the deal.
- The MCP server exposes it.
Added: automations.
GET /v1/automationslists the Pulse automations on the broker's board, with their steps in order. Filter withtype,enabled, andupdated_since.GET /v1/automations/{id}reads one.- Each step has
ask_before_sending. When it istrue, the step puts a draft in the broker's queue instead of sending. POST /v1/automationscreates an automation that sends templates when a deal moves into a stage.PATCH /v1/automations/{id}changes one.- The API saves an automation OFF, and a change turns it OFF again. The broker turns it on in BrokerPlus. Refer to Automations.
- The MCP server exposes all four.
Added: scheduling.
GET /v1/meeting-typeslists the broker's meeting types, with the booking page URL, the form fields, and the questions of each.GET /v1/availabilityreturns the open times of a meeting type. BrokerPlus calculates them the same way as the booking page, with each host's own time zone and split shifts.POST /v1/appointments/bookbooks a contact into an open time. It sends the client the booking confirmation email, the same one the booking page sends. A time that is not open returns409 SLOT_TAKEN.POST /v1/appointments/{id}/rescheduleandPOST /v1/appointments/{id}/cancelmove or cancel a booked appointment. Each one sends the client an email about the change.- The MCP server adds
brokerplus_list_meeting_types,brokerplus_get_availability, andbrokerplus_book_meeting. It does not move or cancel a booking. Every read tool is now marked read-only.
Added: condition writes.
POST /v1/deals/{id}/conditionsadds a condition to a deal.POST /v1/conditions/{id}/satisfyandPOST /v1/conditions/{id}/waivechange its status.- A condition now returns
assignee_role,assignee_contact_id, andassignee_contact_name: who owes it. You can set the first two on a new condition and throughPATCH /v1/conditions/{id}. - A status change through the API now completes or reopens the task that decides the condition, as it does in BrokerPlus.
Added: task cancel, reopen, and notes.
POST /v1/tasks/{id}/cancelandPOST /v1/tasks/{id}/reopen.GET /v1/tasks/{id}/notesandPOST /v1/tasks/{id}/notes.
Added: ten webhook events. contact.created, deal.updated, deal.status_changed, deal.archived, deal.restored, condition.created, condition.satisfied, task.updated, sms.received, and intake.document_uploaded. A deal.updated delivery carries changed_fields, which names the deal fields that changed. See Webhooks.
Added: the webhook delivery log. GET /v1/webhooks/{id}/deliveries lists what BrokerPlus sent to an endpoint in the last 30 days, with the status, the number of attempts, and the last error of each delivery. POST /v1/webhooks/{id}/deliveries/{delivery_id}/retry sends a failed delivery again.
Changed: an endpoint is disabled after 20 failed events, not 20 failed attempts. Before this change, each of the 6 attempts at one event counted as a failure, so 4 bad events could disable an endpoint.
Fixed: webhook deliveries are no longer lost after an outage. Before this change, BrokerPlus looked back only 5 minutes for events to send. Events older than that were never sent. Now BrokerPlus sends every event that it has not sent, for up to 72 hours. A busy brokerage also no longer loses events: internal activity can no longer fill a send cycle before your events.
Changed: a re-enabled endpoint starts from the time you enable it. BrokerPlus does not send the events from the time that the endpoint was disabled.
Added: email and text templates.
GET /v1/templates,GET /v1/templates/{id},POST /v1/templates,PATCH /v1/templates/{id}andDELETE /v1/templates/{id}read and change the email and text templates in the Pulse library. A delete archives the template. See Templates.GET /v1/templates/merge-fieldslists every merge field that a template can use, including your brokerage's custom fields. A template that uses a merge field that is not in the list is refused with400 UNKNOWN_MERGE_FIELDS.- A template sends nothing by itself. A Pulse automation sends it.
- The MCP server exposes every template operation except the archive.
Changed (breaking): every rate on an opportunity is a percent. target_new_rate and
breakeven_rate were decimal fractions. They are now percents, the same as interest_rate. For
example, 0.0499 is now 4.99. If your integration multiplies these two fields by 100, remove
that step.
Added: actions on an opportunity.
POST /v1/opportunities/{id}/convertstarts a new working deal from a tracked mortgage. The deal gets the borrowers and the mortgage facts, and the opportunity stays on the book. The response is the new deal. Each call creates a deal, so sendIdempotency-Keyto make a retry safe.POST /v1/opportunities/{id}/dismisstakes a mortgage off the book and stops its outreach.POST /v1/opportunities/{id}/restoreputs it back.POST /v1/opportunities/{id}/snoozehides an opportunity until the date inuntil, and reminds the broker that morning.POST /v1/opportunities/{id}/unsnoozeends the snooze.- An opportunity now returns
dismissed_at.
Added: the client on an equity report. An equity report now returns contact_id and
contact_name. GET /v1/equity-reports takes contact_id, to list the reports about one client.
Added: the change feed.
GET /v1/changeslists every change to contacts, leads, deals, tasks, intakes, documents, appointments, and communications, in order, with a checkpoint. BrokerPlus writes each entry in the same database transaction as the change, so the feed has every change, from every source.- Each entry gives
record_type,record_id,action(created,updated,deleted,merged, orarchived), the names of the changed fields, and, for a merge,merged_into_id. - Send
after=nowto get a checkpoint before a full sync. Filter withtypes. - BrokerPlus keeps entries for 30 days. An older checkpoint gets
410 CHECKPOINT_EXPIRED. - Webhooks are hints. Use the feed as the source of truth. See Webhooks are hints.
- The MCP server exposes it as the read-only tool
brokerplus_list_changes.
Added: intake progress for each applicant. An intake now contains applicants. Each entry gives
the applicant's name, role, submitted_at, the required questions answered out of total, and
the unanswered questions for each section. The progress moves as the client types, before they
submit. See Intakes.
Added: read an intake's answers. GET /v1/intakes/{id}/answers returns every question each
applicant is asked, grouped by section, with the answer as it stands now. The SIN is never returned.
Added: approve an intake, or ask the client for changes.
POST /v1/intakes/{id}/approveis the same action as Approve in BrokerPlus. The client gets no message.POST /v1/intakes/{id}/request-changesreopens the answers you name and emails the client, the same as a change request in BrokerPlus.
Added: read the drafts you filed. GET /v1/drafts and GET /v1/drafts/{id} return the drafts
that POST /v1/contacts/{id}/drafts filed, with what the broker did with each one. A draft now
returns recipients, sender_user_id, created_by_user_id, scheduled_at, reviewed_at,
communication_id, and updated_at.
Changed: a draft's status can now be scheduled, sent, discarded, or failed. A new draft
is still pending_review. Before this change, status was always pending_review.
Changed: POST /v1/tasks/{id}/complete documents its body. The optional resolution was always
accepted. It is now in the reference, and the MCP tool can send it.
Changed: the MCP server.
- An error now includes the API's
details, such as the matching contacts onDUPLICATE_CONTACTor the fields that failed onVALIDATION_ERROR. - Every tool now has MCP annotations:
readOnlyHint,destructiveHint,idempotentHint, andopenWorldHint. - New tools:
brokerplus_list_task_categories,brokerplus_check_deal_stage_requirements,brokerplus_list_deal_team,brokerplus_get_intake_link,brokerplus_list_intakes,brokerplus_get_intake,brokerplus_get_intake_answers,brokerplus_list_drafts, andbrokerplus_get_draft. The MCP server does not approve an intake or ask a client for changes.
Added: edit the mortgage application one row at a time. See Edit the application one row at a time.
- Applicants, jobs with their pay, other income, assets, liabilities, and other properties each have
a
POST, aPATCH, and aDELETE. A write changes one row, and BrokerPlus then calculates the totals and the ratios again. - A liability from a credit report stays read-only, and a write to it returns
409 FROM_CREDIT_BUREAU. GET /v1/deals/{id}/applicants/{applicantId}reads one applicant, andGET /v1/deals/{id}/other-propertieslists the other properties.
Added: the calculated figures on the application.
GET /v1/deals/{id}/applicationnow returnsgds,tds,ltv, andratio_qualifying_rate, as percents. It also returnstotal_loan_amount,insurance_premium,insurance_premium_rate,insurance_premium_added_to_loan,rate_capped,loan_purpose_renewal,loan_purpose_improvements,improvement_cost,payment_accelerated,insurer_policy_number, andstated_fees, the fees that the lender stated.- The property now returns
appraised_valueandappraisal_date. - A job now returns
incomes, its pay lines. An asset and a liability now returnowner_contact_ids. GET /v1/deals/{id}/application/terms-historylists each change to the loan terms, with who made it and when.
Fixed: a sync with updated_since can no longer skip a row.
- Every list that takes
updated_sincenow also takesafter_id. Send theupdated_atandidof the last row you read, and keeppageat 1. The next page starts after that row. Before this, a row that changed while you paged moved to the end of the list and pushed the next row back onto a page you had already read, so you never saw it. - With
updated_since, every list is inupdated_atorder and thenidorder, oldest first. Rows with the sameupdated_atnow come back in the same order on every request. GET /v1/opportunitieswithupdated_sinceis now oldest first, as documented. It was newest first.GET /v1/campaignsnow filters onupdated_since. It ignored it before.GET /v1/communicationswithupdated_sincenow selects on the newupdated_atfield. It moves when a message is read, starred, filed on a deal, or moved to a different folder. Before this the filter usedcreated_at, so a sync never saw those changes. Every message gets anupdated_atat the time of this release, so your next sync reads all your mail one time.
Added: fields you write can be read back.
- A task returns
priority,pinnedandresolution. - A lead returns
first_name,last_name,emailandphone, from the lead's contact. - A campaign returns
body_markdown: the email body as Markdown that gives exactly the HTML inbody. It is null for a campaign written in BrokerPlus and for an SMS campaign.
Fixed: a campaign written in BrokerPlus returns the HTML that is mailed in body. It returned a
plain-text copy before this.
Fixed: a refused PATCH /v1/deals/{id} saves nothing. Before this, the underwriter_id and
lender_id in a request were saved even when the API refused the stage, status or another field in
the same request. Now the whole request is saved, or none of it is. A stage that needs a lender or an
underwriter is still entered by the request that sets it.
Fixed: a key can no longer stay rate-limited after its minute ends. A rare failure could leave
a key's request count with no end time, and every later request got 429 RATE_LIMITED.
Changed: a query parameter that the API cannot read gets 400 VALIDATION_ERROR.
- An
updated_sincethat is not an ISO 8601 date-time gets400 VALIDATION_ERROR. Before this, the API ignored it and returned the full list. - A filter value that is not allowed, for example
GET /v1/tasks?status=xorGET /v1/communications?channel=x, gets400 VALIDATION_ERRORwith the allowed values inmessage. Some of these returned500before this. - An invalid
deal_id,contact_id,source,status,starts_afterorstarts_beforefilter now gets400 VALIDATION_ERROR. Some lists returned400 BAD_REQUEST.BAD_REQUESTis now only for an ID in the path. details.fieldErrorsnames the parameter.GET /v1/intakes?contact_id=...no longer returns intakes from teams the broker cannot see.
Added: referral partners.
GET /v1/referral-partnersreads the partner book, as the Partners page shows it. For each partner, you see the people they referred, the deals that funded and their value, and the people the broker introduced to them. The figures cover the whole history. Sendperiod(ytd,qtd,mtd), orstartandend, to read a shorter period.GET /v1/referral-partners/{id}reads one partner, with each person, funded deal, and introduction listed.- A deal now returns
referral_partner.POST /v1/deals/{id}/referral-partnersets it from a contact or from a name.DELETE /v1/deals/{id}/referral-partnerclears it. - The MCP server exposes the two reads and the set.
Added: reports. GET /v1/reports/pipeline gives the open deals and their loan amounts on each
stage. GET /v1/reports/funded gives the deals that funded and their volume, in total and for each
month of a period. Both give the same figures as the Business pages. The MCP server exposes both.
Added: merge, duplicates, archive, and more ways to reach a contact.
POST /v1/contacts/{id}/mergemerges the contacts induplicate_idsinto this one, the same as Merge on the Duplicates page. It returns the contact that survives. A merged id now returns410 CONTACT_MERGEDonGET /v1/contacts/{id}, with the survivor's id indetails.merged_into_id.GET /v1/contacts/duplicateslists the sets of contacts that look like the same person.POST /v1/contacts/{id}/archiveandPOST /v1/contacts/{id}/unarchivetake a contact out of the book and put it back. A contact now returnsarchived_at.GET,POSTandDELETEon/v1/contacts/{id}/methodsread, add and remove the extra emails, phones and social profiles on a contact. A social profile returns itsurl.GET /v1/contacts/{id}/relationshipslists the people a contact is related to.- The MCP server exposes the merge and the three reads. The merge tool is marked destructive, so an assistant asks before it merges.
Added: a broker's licences. A user now returns licenses: one entry for each province, with the
licence class and the day it expires.
Docs: corrections and pages for AI agents. The API did not change.
- Pagination now gives the real order of each list. Not every list is newest first.
- The Introduction now says that you can update the loan terms and the property address on a deal.
- Errors now lists
409 MULTI_TEAM_UNAVAILABLEand503 TRY_AGAIN. - Every page is also available as Markdown at its URL plus
.md./llms.txtindexes the pages, and/llms-full.txtcontains all of them. - The examples show curl, TypeScript, and Python.
- New guides: Capture leads from your website or ads, Sync your book, Migrate from another CRM, and Build a Claude command center.
Added: document uploads.
POST /v1/deals/{id}/documentsadds a file to a deal. Send it asmultipart/form-data(50 MB maximum), or as JSON withcontent_base64(10 MB maximum). You can also senddocument_type,contact_id, andname. BrokerPlus stores, classifies, and checks the file the same way it does for a file that a broker uploads. See Files.- A new
document.uploadedwebhook fires when a file is added to a deal by a broker, by the API, or from an email. GET /v1/deals/{id}/document-requestslists the documents that a client still owes on a deal.GET /v1/document-typeslists the codes fordocument_type.- The MCP server exposes the upload, in base64, and both lists.
Added: more fields and filters on documents.
- A document now returns
contact_name,display_name,document_type_label,stage,verified,folder,uploaded_by_user_id, anduploaded_by_name. uploaded_vianow returns a fixed set of values, and can beapifor a file that this API uploaded.GET /v1/deals/{id}/documentstakesverified,document_type,contact_id, andupdated_since. Anupdated_sincethat is not a date returns400.
Added: find a contact or a lead by email or phone.
GET /v1/contactsandGET /v1/leadstakeemail,phone, andq. Theemailmatch ignores case. Thephonematch compares the last 10 digits, so any format works. Both match the main value and any additional email or phone on the contact.qis the same text search as the search bar in BrokerPlus.- On
GET /v1/leads, each filter matches the lead's contact. No match returns an empty list, not404.
Added: update, archive, and convert a lead.
PATCH /v1/leads/{id}changes the stage, service type, first-time buyer flag, follow-up date, details, referral source, and channel. The name, email, and phone stay on the contact.POST /v1/leads/{id}/archiveandPOST /v1/leads/{id}/unarchivetake a lead out of the funnel and put it back.POST /v1/leads/{id}/convertstarts a deal from the lead. You can name the dealtype,board_id, andstage_id. A second call returns the same deal.- A lead now returns
status(open,archived, orconverted),converted_deal_id,referral_source_id,channel_id, and the name next to each id. GET /v1/lead-stages,GET /v1/referral-sources, andGET /v1/lead-channelslist the ids that a lead takes.
Added: custom fields on leads, and filters by custom field.
POST /v1/leadsandPATCH /v1/leads/{id}takecustom_fields, a map of fieldkeyto value. A lead's custom fields are the fields of its contact. One bad key or value refuses the whole request, anddetails.custom_fieldsnames each one.GET /v1/leads/{id}/custom-fieldsandPATCH /v1/leads/{id}/custom-fields/{key}read and set them one at a time.GET /v1/custom-fieldslists the field definitions. Sendentity=contactorentity=dealto list one kind.GET /v1/contacts,GET /v1/leads, andGET /v1/dealstakecustom_field[<key>]=<value>.- The MCP server exposes the lookup, the lead update, archive and unarchive, the conversion, and the lead custom fields.
2026-10-06
Added: deal custom fields.
GET /v1/deals/{id}/custom-fieldsreads the custom fields your brokerage keeps on a deal.PATCH /v1/deals/{id}/custom-fields/{key}sets one. They work the same as the contact custom fields: address a field by itskey, and send an empty string to clear a field.- The MCP server exposes both.
Added: the short_text custom field type. A custom field can now have the type short_text. It holds one line of 200 characters or fewer. When you set one, line breaks in the value change to spaces. A longer value returns an error.
2026-10-05
Added: you can correct what a tracked mortgage carries.
PATCH /v1/opportunities/{id}takesbalance,interest_rate,prime_adjustment,monthly_payment,property_value,effective_penalty, andpenalty_type. Send only the fields you are changing.interest_rateandprime_adjustmentare percents, although the other rates on an opportunity are decimal fractions.- A balance you send becomes the new anchor. BrokerPlus pays it down from that day onward, and neither the nightly recalculation nor an import overwrites it. Send null to hand the balance back to BrokerPlus.
- A rate you send also lands on the mortgage application, so the deal and the book agree.
- An opportunity now returns
balance_is_manual,interest_rate,prime_adjustment, andpenalty_type. GET /v1/opportunitiestakesdeal_id. A deal does not carry the id of its opportunity, so this is how you go from a deal to the mortgage it tracks.effective_penaltynow returns the penalty a broker entered from a lender payout statement, when there is one. Before this it returned only the penalty BrokerPlus calculates.
2026-10-03
Added: express_send on campaigns.
POST /v1/campaigns/{id}/scheduletakes an optionalexpress_send. When it istrue, the whole audience gets the campaign within about two hours ofscheduled_at, andsend_window_daysis ignored. A fast send from one mailbox is more likely to go to spam, so use it only when speed matters more than delivery.- A campaign now returns
express_send.
Changed: paced sends wait for daytime. Without express_send, a campaign only sends between 8 AM and 8 PM. A recipient whose address places them in a Canadian province gets it on their own clock; everyone else goes by the time zone of the person who created the campaign. A scheduled_at outside those hours starts at the next 8 AM, and each day of a multi-day send stays inside those hours.
Added: skip_weekends on campaigns. POST /v1/campaigns/{id}/schedule takes an optional skip_weekends, which holds a paced send over Saturday and Sunday and carries on Monday at 8 AM. A campaign now returns skip_weekends.
Added: warnings on a schedule. POST /v1/campaigns/{id}/schedule now returns warnings, a list of plain sentences to pass on to the broker: one day of the send close to the daily sending limit of their connected mailbox (Google Workspace 2,000, Gmail 500, Microsoft 365 10,000, Outlook.com 1,000), or an Express send starting outside 8 AM to 8 PM. The campaign is scheduled either way.
Changed: a busy database no longer fails a schedule with a bare 500. POST /v1/campaigns/{id}/schedule now answers 503 TRY_AGAIN when BrokerPlus is too busy to finish. The campaign stays a draft and nothing is sent, so send the same request again after a short wait.
2026-10-01
Added: the client intake works over the API. See Intakes.
GET /v1/intake-linkreturns the broker's standing intake link, the one that never expires.PATCH /v1/intake-linkturns it on or off, and the url stays the same through a disable.GET /v1/intakeslists the intakes a client is filling in, with filters forstatus,deal_id,contact_id, andupdated_since.GET /v1/intakes/{id}reads one.POST /v1/intakesasks one client for an intake. A deal is optional, a second applicant can be named, anddeliveryofemailhas BrokerPlus send the link from the broker's own mailbox.POST /v1/intakes/{id}/linkissues a fresh link for a client. BrokerPlus keeps only a fingerprint of a link it has sent, so a link cannot be read back. Every link issued for the same intake works until it expires.- Two new webhooks:
intake.startedwhen a client first opens an intake, andintake.submittedwhen they send it back.
Added: a connected mailbox is readable over the API.
- A communication now returns
from,to, andcc, so you can see who an email was between. - A communication now returns
body_html, which is the HTML the sender wrote. It arrives exactly as it was sent and it is never sanitized, so sanitize it before you render it. - A communication now returns
attachments, which names each attached file, its type, and its size. GET /v1/communications/{id}/attachments/{attachment_id}returns a signed link to one attached file, valid for five minutes. BrokerPlus gets the file from the mail provider the first time somebody asks for it. If the mailbox no longer holds the message, the response is410 ATTACHMENT_UNAVAILABLE.- A communication now returns
read_at, which is null for mail nobody has opened, andstarred. - A communication now returns
folders, which is every folder and label the message sits in, as your mail provider names them, andmailbox, which is the connected address it arrived at. GET /v1/communicationsnow filters onthread_idfor one conversation, onunreadfor mail nobody has opened, and onfolderby role (inbox,sent) or by the provider's own folder name.- A new
email.receivedwebhook fires when mail arrives in a connected mailbox. Junk mail and the history BrokerPlus imports when a mailbox is first connected do not fire it.
A key reads the mailboxes its own broker can read in BrokerPlus. A teammate who has not shared their mailbox is no more readable through the API than through the app.
2026-09-28
Added: you can name a deal, record its lender file number, set the date it funded, and archive it.
PATCH /v1/deals/{id}now takesname, which is the name a broker gives a deal. Send null or an empty string to put the deal back on your brokerage's naming pattern. A deal now returnsname.PATCH /v1/deals/{id}now takeslender_file_ref, which is the lender's own file number for the deal. Use it for a number that comes from somewhere other than BrokerPlus.reference_numberstays ours, and stays read-only.PATCH /v1/deals/{id}now takesfunded_at, so a deal that funded before it reached BrokerPlus carries its real funding date. It is only accepted on a deal that is funded, or in the same request that setsstatustofunded. On any other deal it returns409 NOT_FUNDED.DELETE /v1/deals/{id}archives a deal. The deal leaves every board and report, and a broker can restore it in BrokerPlus. It is the same archive the dashboard runs, so the deal's open tasks and queued messages stop with it.
Added: the mortgage application takes the purchase price, the payment, the insurer, and two more dates.
PATCH /v1/deals/{id}/applicationnow takespurchase_price,payment_amount,payment_frequency,mortgage_insurer,interest_adjustment_date, andfunding_date.- The application now returns
interest_adjustment_dateandmortgage_insurer. PATCH /v1/deals/{id}/propertynow takesoccupancy_typeandoccupancy_purpose.
Fixed: a stage requirement with a fixed list of choices now says what it takes.
- Filling a requirement such as the property's province or the payment frequency with a value that is not on its list returned
500. It now returns400, and the message names every value the field accepts.
2026-09-27
Added: you can write the team roles, the mortgage terms, and the property address of a deal.
GET /v1/deals/{id}/teamlists the users in your brokerage who hold a role on the deal, e.g.Sales Manager.POST /v1/deals/{id}/teamfills a role, andDELETE /v1/deals/{id}/team/{role}empties it.- A team role is one of your own users. A participant is a contact from outside your brokerage, e.g. a lawyer. They are different lists.
PATCH /v1/deals/{id}/applicationchanges the loan amount, rate, rate type, term, amortization, first payment date, and financing condition date. Rates are percents.PATCH /v1/deals/{id}/propertychanges the property address.PATCH /v1/deals/{id}now also takesunderwriter_idandlender_id. A deal now returns both fields.- The mortgage application now returns
financing_condition_date.
Added: GET /v1/deals/{id}/stage-requirements tells you what a deal needs before it moves to a stage.
- Send the stage as
stage_id. The response lists each missing requirement. It is the same check that a move runs, so an empty list means the move passes the stage requirements. - Use it before a move, instead of reading the
missinglist from a409response.
Added: a campaign can have follow-ups, and each one is a campaign with follow_up_of set.
- A broker adds up to three follow-ups to a draft campaign in BrokerPlus. Each follow-up goes out a set number of days after the previous message, and only to people who did not reply.
GET /v1/campaignsreturns each follow-up as its own campaign.follow_up_ofis the id of the campaign that it follows.follow_up_delay_daysis the number of days that it waits. On an original campaign, both fields are null.POST /v1/campaigns/{id}/schedulerefuses a follow-up withNOT_A_ROOT. A follow-up goes out with the campaign that it follows.- The same endpoint refuses a
recurrenceon a campaign that has follow-ups, withFOLLOW_UPS_WITH_RECURRENCE. A campaign can repeat, or it can have follow-ups, but it cannot do both. - The API cannot add or change follow-ups. The broker sets them in BrokerPlus.
2026-09-26
Changed: a lead you send with POST /v1/leads now has the source api, and starts the same automations as a lead form.
- Before this change, the lead had the source
manual. A manual lead does not start the "New lead created" automation, and it does not send thelead.createdwebhook. A lead from the API now does both, the same as a lead from a BrokerPlus lead form. - A lead that a broker types in BrokerPlus is still
manual, and it still starts nothing. sourceon a lead can now beapi. If your code readssource, accept the new value.
Fixed: a deal with no type no longer fails GET /v1/deals.
typeon a deal can now benull. A deal made from a lead has no type until the broker sets one.- Before this change, a page of
GET /v1/dealsthat held such a deal returned500, and so didGET /v1/deals/{id}for that deal.
Fixed: a lead from a shared client link no longer fails GET /v1/leads.
sourceon a lead can beportal. The contract did not list it, so a page that held such a lead returned500.
2026-09-25
Changed: a deal's contacts now carry role_label, which is what tells one realtor from the other.
- Both agents on a purchase hold the same
realtorrole, so the seller's agent is told from the buyer's by the brokerage's own word for the seat -Listing RealtorandBuying Realtor. - The participant endpoints already returned
role_label. Reading a deal now returns it too, so naming one of the two agents takes one request instead of two. - To record the distinction, attach the partner with
role: "other"and your ownrole_label.
Added: POST /v1/campaigns/{id}/schedule sets the time a campaign goes out.
- The campaign must be a draft. Send
scheduled_at, and optionallysend_window_daysto spread the send, orrecurrenceto repeat it. - The recipient list is frozen at the moment you schedule. Until the campaign fires, the broker can still pause or delete it in BrokerPlus.
- There is still no endpoint that sends a campaign immediately. A schedule names a future time, which is what makes it safe to publish.
- The endpoint refuses a campaign whose audience resolves to nobody, and one whose brokerage has no CASL sender identity. The MCP server exposes it as
brokerplus_schedule_campaign.
Changed: body on POST /v1/campaigns is Markdown, and now becomes real formatting.
**bold**,*italic*,[text](https://example.com),#headings, and-or1.lists render as formatting in the email. Before this change the asterisks reached the client as text.- Write Markdown, not HTML. Tags in this field are shown to the client as text. This protects a broker's own mailbox from sending markup it did not write.
- An SMS campaign is unchanged: it sends the body as plain text, with no formatting.
bodyon a campaign you read back is the HTML that is mailed, because that is what BrokerPlus stores.
2026-09-23
Added: campaigns, audiences, contact custom fields, and equity reports.
GET /v1/campaignsandGET /v1/campaigns/{id}read your newsletters and mass messages. Each campaign carries aresultsobject with the counts per outcome, which includesopenedandunsubscribed. The counts come from the recipient rows, so they agree with what BrokerPlus shows you.GET /v1/campaigns/{id}/recipientsreads the result for each person: the contact id, the status,opened_at, andunsubscribed. Filter it withstatusor withopened. Clicks are not recorded. BrokerPlus does not rewrite the links in your message, so no endpoint reports a click.POST /v1/campaignscreates a campaign as a draft.POST /v1/audiencessaves the list of contacts to send it to, andGET /v1/audienceslists the ones you have. An audience is a fixed set of contacts, not a saved filter: a contact who matches your criteria tomorrow does not join a list that you save today.- The API never sends a campaign, and never schedules one. The broker opens the draft in BrokerPlus, reads it, and sends it there. There is no endpoint that sends, and this release does not add one.
GET /v1/contacts/{id}/custom-fieldsreads the custom fields your brokerage keeps on a contact.PATCH /v1/contacts/{id}/custom-fields/{key}sets one. Address a field by itskey, which does not change when somebody renames the label. Send an empty string to clear a field.GET /v1/equity-reportsandGET /v1/equity-reports/{id}read the monthly reports sent to past clients. The figures are the snapshot the client received, not today's numbers; read today's numbers fromGET /v1/opportunities.cta_clicked_atis the client asking for a call.- The MCP server exposes all of these, except the campaign send that does not exist.
2026-09-22
Added: POST /v1/contacts/{id}/drafts files a message for the broker to review.
- Send a
channelofsmsoremail, and abody. The draft lands in the review queue of the broker your key acts as, with the statuspending_review. - The API never sends a draft. The broker reads it in BrokerPlus, and approves, edits, or rejects it there. There is no endpoint that sends, and this release does not add one.
- Use this endpoint when your own system, or an assistant that you run, writes the message and a person must read it before a client does. See Drafts.
- The MCP server exposes the endpoint as
brokerplus_create_contact_draft.
2026-09-21
Added: a key can be created with read-only access.
- When you create a key in Settings > Developer, set its access to Read only. Such a key answers a
GETrequest and refuses every other method with403and the codeREAD_ONLY_KEY. See Authentication. - The access is set once, at creation, and you cannot change it afterward. Revoke the key and create another one.
- Every key that existed before this date has full access, and its behaviour does not change.
GET /v1/menow reportsapi_key.read_only.
2026-09-13
Changed: a deal's status is one of a fixed set of words.
statuson a deal is now one ofactive,submitted,approved,funded,closed,dead,declined,cancelled,expired,withdrawn, orunknown. A deal that carriednewnow carriesactive. A word that the set does not contain now readsunknown. The field type is unchanged: it is a string.- The
statusfilter onGET /dealsaccepts the same words.
2026-09-10
Added: an MCP server, contact statistics, deal lookup by external reference, deal commission, deal consents, communication preferences, deal participants, team members, contact addresses, Finmo lenders and submissions, stage history, deal and task creation, and task assignment.
-
/deals/{id}/participantslists, attaches, updates, and removes the contacts on a deal, with their role. Borrower and partner roles share one list, andis_partnerseparates them. A partner with roleothercarries your ownrole_label. The endpoint supportsIdempotency-Keyon create. -
GET /teams/{id}/memberslists who is on a team, their role on it, and their title. -
The MCP server lets an AI assistant call the API with your key. Each tool is one documented endpoint, with the same inputs. It publishes reads across the API and the supported creates and updates. It publishes no delete, no webhook administration, no consent or commission write, and no document URL.
-
GET /contacts/{id}/statisticsanswers a contact's deal counts, funded volume with its basis, repeat-client standing, referrals, and last touch. -
A deal now carries
lender_file_refandexternal_references: its ids in Velocity, Filogix, or Finmo.GET /dealstakesexternal_reference,source, andlender_file_refto find a deal by one of them. Matches are exact. -
/deals/{id}/commissionreads, records, changes, and removes what the brokerage earns on a deal, with its line items and its splits. The same compensation access rule as the dashboard applies. The endpoint supportsIdempotency-Keyon create. -
/deals/{id}/consentslists and records the consents on a deal.POST /deals/{id}/consents/{consentId}/revoketakes one back and keeps the row. Both POST endpoints supportIdempotency-Key. -
/contacts/{id}/communication-preferencesreads and changes a contact's email and SMS consent, by category.opt_inclears a withdrawal and never records express consent. -
/contacts/{id}/addresseslists, adds, updates, and removes a contact's addresses. Exactly one address is primary. Provinces use two-letter codes, and countries useCA,US, orother. The endpoint supportsIdempotency-Keyon create. -
GET /lendersandGET /submissionsnow include the lenders and submissions of the brokerage's connected Finmo account, markedsource: finmo. The brokerage's own records are markedsource: brokerplus. Both endpoints accept asourcefilter. A Finmo submission carrieslender_name,lender_status,funded_at,loan_amount,interest_rate, andterm_months. Theslug,attempt, andstatusfields are now nullable. -
GET /deals/{id}/stage-historylists every stage move on a deal, newest first, with the stage it left, the stage it entered, who moved it, and when. The same record feeds thedeal.stage_changedwebhook. Imported deals carry history only from their import date onward. -
POST /dealsopens a deal for the key's broker. It lands on the broker's default pipeline for its type, or on the pipeline you name, and takes that pipeline's team. Attach borrowers withcontacts. The endpoint supportsIdempotency-Key. -
POST /tasksfiles a manual task. The task takes the team of its deal or contact, or the broker's own team. Sendassignee_user_idto assign it, or leave it blank to file it unassigned. The endpoint supportsIdempotency-Key. -
PATCH /tasks/{id}acceptsassignee_user_id. Reassignment applies the dashboard's eligibility rule. An ineligible assignee returns400 INVALID_ASSIGNEEand changes nothing. Sendnullto unassign.
2026-09-08
Corrected: access checks and existing writes. These corrections add no new endpoints.
- Deal and contact requests enforce the broker's team access, including related notes, documents, conditions, and submissions.
- Deal updates use the dashboard's stage checks, compliance rules, and owner handoff. Status writes accept
active,dead,closed, orfunded. - A combined deal update commits its fields and events together. A later notification or closing action can still fail after that commit.
- Contact edits preserve calculated client types and enforce identity locks. Condition edits enforce the parent deal's lock.
- Deal closing and maturity dates accept
YYYY-MM-DDor an ISO timestamp. Responses remain date-only strings. - New notes inherit their parent's team, sanitize HTML, and record eligible mentions.
- A saved response requires the original API key, broker, and current access to its result. Access loss returns
404without repeating the mutation.
Read Idempotency before retrying a write with an uncertain result. No new endpoints are included in these corrections.
2026-08-15
Added: the surface grew from 40 endpoints to 60. Read the sections below for what is new.
Deals now expose the mortgage itself.
GET /deals/{id}/applicationreturns the loan: amount, term, amortization, rate, and payment.GET /deals/{id}/propertyreturns the property that secures the loan.GET /deals/{id}/applicantsreturns everyone on the application, with their employment history and their income.GET /deals/{id}/financialsreturns the assets, the liabilities, and the down payment sources.
Every lender-coded field on these endpoints arrives as a code and a readable label. A code that
we cannot name gives you a label of Unknown, so that "we hold a value that we cannot name" stays
different from "there is no value".
Added: the opportunity book. GET /opportunities and GET /opportunities/{id} return the
mortgages that your brokerage tracks, with the balance, the penalty to break, and the savings from a
move.
Added: appointments. GET, POST, PATCH, and DELETE on /appointments. An appointment
that BrokerPlus synced from Google Calendar or from Outlook returns 409 on a write. Change that
appointment in the calendar that owns it. A write here would look like a success, and the next sync
would silently undo it.
Added: submissions. GET /submissions, GET /submissions/{id}, and
GET /submissions/{id}/decisions return the deals that a broker sent to a lender, and what each
lender answered.
Added: communications. GET /communications and GET /communications/{id} return the email,
the calls, and the messages on a deal or a contact.
Added: your brokerage and your teams. GET /organization, GET /teams, and GET /teams/{id}.
Added: PATCH /conditions/{id}. You can now mark a condition satisfied, waived, or outstanding.
You cannot write lender_status. The lender owns that value, BrokerPlus refreshes it on each
decision poll, and a value that you wrote here would tell a broker that the lender accepted
something that the lender never saw.
Breaking: a calendar date is now a YYYY-MM-DD string. The affected fields are closing_at,
maturity_date, first_payment_date, funding_date, and rate_hold_expires_at.
Code
These columns hold a date. They hold no time and no time zone. As a timestamp at midnight UTC, every client west of UTC rendered the day before. On a maturity date, that is a wrong answer, not a formatting preference. A write still accepts either form.
Changed: the documentation is now written in Simplified Technical English. No behaviour changed. The pages follow ASD-STE100, constrained by the Google developer documentation style guide, so that they read the same way for a non-native reader and for a translation tool.
Still out, on purpose. You cannot create a deal or a task, reassign a task, or upload a file. The API does not return an applicant's social insurance number, a liability's account number, a credit report, a lender rate sheet, or compensation. Each page explains the reason where the subject comes up.
2026-08-08
Added: the surface grew from 16 endpoints to 40. Nothing that was already published changed shape, so no existing integration needed a change.
- Users (
GET /users,GET /users/{id}) and Pipelines (GET /pipelines,GET /pipelines/{id}). These close a gap. The fieldsowner_id,assigned_broker_id,assignee_user_id,board_id, andstage_idwere published as ids with nothing to resolve them against. They now resolve. - Documents (
GET /deals/{id}/documents,GET /documents/{id}) and Conditions (GET /deals/{id}/conditions,GET /conditions/{id}). A download URL expires after five minutes. See Files. - Notes on a contact and on a deal, both read and write.
- Tags: the two vocabularies (
GET /contact-tags,GET /deal-tags), and assign and unassign on both parents. - Lenders (
GET /lenders). PATCH /deals/{id}for status, stage, assigned broker, and the closing and maturity dates. The API rejects a stage from a different pipeline, and a broker from a different brokerage.PATCH /tasks/{id}for the title, the body, the due date, and the pinned flag.PATCH /webhooks/{id}for the URL, the events, and the enabled flag. When you enable an endpoint again, the API clears its failure count.
Added: How the objects fit together, a map of which id resolves through which endpoint.
2026-08-03
Added: Idempotency-Key on every POST. Send the header to make a create safe to retry. The
API replays the first response instead of creating a second record. The header is optional, and a
request without it behaves as it did before. See Idempotency.
Breaking: the pagination envelope is now snake_case. pageSize became page_size, and
totalPages became total_pages. They now match the page_size query parameter, and every other
field on the surface.
Code
The old wrapper came from an internal helper that serves our own dashboard, and it would have kept moving with that dashboard. We changed it on the day that we published the API, before anybody read it.
Changed: the reference now documents every field. Behaviour did not change. The OpenAPI document described about a quarter of its fields before. It now describes all of them.
Changed: success is published as a plain boolean. Behaviour did not change. The value is still
true on a success and false on an error, and the field says so. OpenAPI 3.0 has no const, so
the fixed value was a single-value enum, and the reference rendered that as an empty "Enum values"
chip on every response.
2026-08-03: beta
The first public release. It had 16 endpoints, across identity, contacts, leads, deals, tasks, and webhooks. A key from Settings > Developer authenticated all of them.