Release notes

What shipped, and when. Newest first. Page 1 of 5.

A campaign will not send a sentence with a hole in it

campaignssmstemplates

The first SMS campaign sent from the new screen went out reading "Just a reminder about your appointment tomorrow at." — no time, and a dangling "at".

What happened

The message was loaded from one of the saved templates that ship with the product: "Hi {first_name}! Just a reminder about your appointment tomorrow at {time}." That template is written for one appointment, where an automation knows the time. A campaign does not — it has one message and a list of people, and the only things it can fill in are the five on the Personalize row: {first_name}, {last_name}, {full_name}, {company_name}, {agent_name}.

A variable outside that set is dropped at send time, and the punctuation tidied up behind it. That is the right behaviour for a contact with no last name on file — "Hi there," beats "Hi ,". It is the wrong behaviour for {time}, because nothing is missing from the contact; the value never existed. The sentence closes over the gap and the recipient reads a bug.

The composer did notice. It showed an amber note saying {time} would be left blank — and the launch button stayed lit, so the note got launched past. A warning on a screen with a working button is a warning nobody reads.

What changed

  • An unfillable variable now blocks the launch. The composer names it, names the five it can fill, and asks for real words in its place.
  • The template cards say so before you click. A saved template or automation carrying a variable a campaign can't fill is marked "Written for one contact — you'll need to replace {time} with real words."
  • The sender checks too. A campaign that reaches the dispatcher with such a message is refused before the first text, with no ledger rows written, so you can fix the wording and run the same list again.

There is deliberately no "remove the variables for me" button. Deleting {time} leaves "your appointment tomorrow at." — the same broken sentence. Only the person writing it knows what it was meant to say.

SMS campaigns

campaignssmscomplianceoutreach

Campaigns had a Voice tab and an Email tab. The channel most stores actually use to ask a past customer a question was the one you could not run a campaign on.

What you could do before, and why it wasn't this

Automations could send a text, and still can — that is the right tool for "when X happens, text them". A campaign is the other shape: one message, to a list you choose, now. The closest thing was an automation with a manual trigger and its Run now picker: search for a contact, click them, repeat, 200 at a time, with no audience filter, no daily limit, and nothing afterwards that told you how many replied.

Worse, a campaign could already be stored as an SMS campaign — the API and the assistant both offered the type — and the dispatcher never read the type. Such a campaign either sat as a draft forever or, once activated, placed phone calls. That is fixed: each channel now runs on its own path, and an email campaign asked of the wrong dispatcher is refused rather than dialled.

What Campaigns → SMS does

Pick the audience by tag, write the message, set the schedule, launch.

  • One message per contact. Not a rule the dispatcher tries to follow — a database constraint. A campaign nudged every fifteen minutes cannot text the same person twice.
  • A daily limit that means a day. Counted from midnight in the campaign's own timezone. A list longer than the limit resumes the next day where it stopped.
  • Personalization. {first_name}, {company_name} and the rest are filled per contact, and a contact with nothing on file gets the sentence without the variable, not a blank token.
  • The opt-out line is added for you unless your own text already offers one.
  • Every send goes through the same compliance chain as every other text this platform sends: 10DLC registration, do-not-call, prior STOP replies, the recipient's local quiet hours and the state solicitation windows on top. A contact held back for quiet hours is texted when their window opens; one who has replied STOP is never reconsidered.
  • Results, not sends. Replies and opt-outs are matched back to the campaign that prompted them, so the card reads sent / replies / opt-outs and the send log gives a reason for every contact who was not texted.

Sending stops the moment something is wrong at the account level — texting not registered yet, verification unfinished — instead of writing the same refusal two thousand times.

Connect your own AI assistant to your account

aiintegrationscompliancedealership

You can now give your own AI assistant access to your dealership account. Not our copilot inside our app — your assistant, in whatever window you already use it, working on your data through the same rules your staff work under.

Setup takes about ten minutes and is written up at Connect your AI assistant.

What it can do

Fifteen tools. Eight of them only look: search contacts, open a contact, list deals, open a deal, list appointments, pull a call, check the org's status, and check whether there is a lawful basis to contact somebody before doing it.

Seven of them act: create and update a contact, log an activity, move a deal stage, book an appointment, send a text, and place an outbound call.

So "which of my leads from last week never got a second call" is a question you can now ask in plain English and get answered from your actual records, and "text the three of them and book anyone who replies" is a thing you can ask for next, once you have decided you trust it.

The key decides which store it can see

You create a key in Settings, and the key is what says which account the AI is working in. Nothing in any request can select a different store, because the store is read off the key. There is no key that sees two accounts.

Start read-only. A read-only key lets the assistant look at everything and change nothing, and watching it work for a few days before it can text anybody is a sensible order to do this in. Add a second key with write access when you are ready, and revoke either in one click.

Texts and calls go through your existing rules, not around them

This is the part worth understanding, because it is where a connector like this usually goes wrong.

When the AI sends a text or places a call, it does not send it itself. It goes to the same place the buttons in the app go to, so the consent check, the calling hours, the wallet balance, the number rotation and the AI disclosure all run once, in the same order, with the same answers. There is no second copy of that logic that can drift, and the first drift nobody notices is the one that texts somebody at three in the morning.

An assistant can therefore place a compliant call. It cannot override a compliance warning the way a manager can — that door is simply not there for it.

One rule applies to the AI and not to your staff. Marketing texts and AI marketing calls need an actual consent record. The assistant is allowed to say a message is transactional, but that claim is checked against a real appointment, a real deal, or a message the customer sent you first. An exemption a model can type is not an exemption.

You can see everything it did, including what it was refused

Every tool call writes a line: which key, which tool, when, and what happened. Refusals are written down too, and they are the half worth reading — the log answers "what has this thing been doing on my account, and what did you stop it from doing".

The arguments are not stored. They carry message bodies and customer phone numbers, so a fingerprint of them is kept instead of the text.

There are per-account ceilings on how much calling and texting a connector can do, counted across the whole store, so adding a second assistant does not double how many strangers an AI can dial.

The honest limits

Texting and calling from a connector are off until switched on for your account — reads work without it. When the AI is refused something, it is told why and what would fix it, in a form it can repeat to you, rather than being handed an error that makes it tell you the integration is broken. And an assistant working from your records will still be confidently wrong sometimes; the read-only key exists so you can find out how often before it can act.

Book values now have one place to come from

dealershipdesklendersvaluation

The book-out sheet has always printed a number somebody typed. This is the plumbing for a day when it prints a number a book quoted — and an honest account of how far off that day still is.

Nothing you see changes today

The product does not pull live book values. There is a Kelley Blue Book provider in the code now, written against their InfoDriver sandbox, and the sandbox is all it can reach: the production hosts refuse us because the agreement is not signed. Sandbox figures are roughly six months out of date and come back carrying KBB's own notice that they are not a real valuation.

So the book-out sheet is untouched. No screen shows a fetched number, no submission carries one, and nothing you do on a deal behaves differently than it did last week. If you want a book value on a sheet today, you still type it in.

That the sheet is untouched is the point of the work, not an omission from it.

Why the plumbing was worth doing first

Two reasons, both of them about your deals rather than about the code.

The first is that no single book satisfies two banks. Lendmark advances against J.D. Power, Reliable Credit prefers KBB and takes nothing else, and a store that sends the same car to both needs both numbers on the same deal. So the setting that decides which book answers lives on the lender, not on the store. That is already how your lender directory is shaped; the valuation side now matches it.

The second is that KBB's own service is being retired. InfoDriver is going away in favour of a newer one, targeted for the end of 2026 and already slipping. Building against it directly would mean doing this whole job twice. Behind a seam, the switch is one file.

Two things it refuses to guess

Clean retail, average retail and rough trade can be thousands apart on the same car, and a lender advances against one of them specifically. So a fetched value never picks a category on your behalf — the caller has to say which figure it is printing. A sheet that guesses what it is printing is worse than one that says it does not know.

And when a book does not quote a particular figure, that figure comes back empty rather than filled in with the nearest one the book did quote. A sheet headed "rough trade" carrying an average trade number is a document a lender makes decisions on.

Same rule on a VIN that decodes to several trims: you get the list of possibilities, not whichever one sorted first.

The lending value question, stated plainly

Lending value — what a bank will advance against — and typical listing price are both returned, and neither is treated as a book value. They are their own fields with their own headings, because a lending value is not a retail figure and filing it as one would quietly change what every existing deal's stored answer means.

There is an unresolved disagreement about showing the lending value at all. KBB's display requirements prohibit publishing lending value and auction value outside internal use. Cox's own product team told us in writing on 9 September that lending value belongs on a book-out sheet. Those cannot both be followed, so the lending value is fetched and held but not printed unless a specific approval flag is set, and the conflict is on the list of things to settle in the contract rather than resolved by whichever reading is more convenient.

Auction value is not mapped onto the wholesale figure for the same reason. They are different numbers, and treating one as the other on a document a lender reads is the kind of shortcut that gets noticed later.

Credit applications built to go to Dealertrack, and decisions built to come back

dealershiplenderscreditcompliance

Everything this system did with a credit application before today ended with a person carrying it: an email draft somebody read and sent, a set of fields somebody typed into RouteOne. There is now a rail built to send it directly.

Read the next paragraph before you read anything else.

What this is, and what it is not

This is built against the Dealertrack API and is in certification with Cox. It is not live, it is not connected to a bank, and no real customer's application has gone through it. Every environment is set to Dealertrack's sandbox, and no live call has ever completed. The wiring, the field mapping, the refusals and the logging are written and tested; the send itself is documented, not proven.

When it does carry a real application, the first one should be watched by a person, and this note will be replaced by one that says so.

A person approves every submission, three separate ways

A credit application leaving the building puts a hard inquiry on somebody's bureau file. That is not recoverable, so the path is deliberately hard to fire by accident.

The request has to carry an explicit confirmation flag — it is never assumed from the fact that a request arrived, so a stale browser tab or a copied command sends nothing. The lender has to be marked as an API lender in your lender directory; that is a separate setting, not a loosened default. And the submit button takes a second deliberate click, but only for this channel. Recording a submission you emailed or faxed yourself still takes one click, because a confirmation people dismiss by reflex is worse than no confirmation.

There is no queue, no retry, no cron and no background job anywhere on this path. "Try again automatically" would mean a second hard inquiry on somebody's credit report that nobody asked for.

The same application cannot go to the same lender twice over the API. If it is tried, you get the first submission's reference back and a sentence explaining it, rather than a second inquiry. Submissions you hand-carried are unaffected — if you emailed Lendmark twice, you did in fact send two emails.

Everything sent and received is kept, with the sensitive parts removed

When a lender says an application is wrong, the first question is what exactly was sent. Both sides of every exchange are recorded — but the social security number, date of birth, driver's licence and income are stripped out of the copy first, on the way in and on the way back. A lender echoing the applicant back at us would otherwise smuggle the SSN into a table nobody thinks of as holding it.

Phone number and email are deliberately left readable. Hiding them would be for show, and would make the log useless for the most common real failure, which is a wrong phone number.

Decisions arrive on their own, and you can also just ask

When a lender answers, the answer lands on a callback and updates the deal: status, approved amount, rate, term, tier, stipulations, decline reasons, and the analyst's message.

A callback is a promise about a network, and every way one quietly fails looks identical from the desk — the bank has gone quiet. So there is also an Ask the lender button. It fetches the current decision on demand. Nothing polls: no interval, no cron, no background job. It is a read at the far end, so nothing reaches the lender, no application moves and no credit is pulled, which is why it needs no confirmation step of its own.

A pushed decision and a fetched one go through the same reader, so the two can never disagree about what a number means.

One outcome is deliberately left unmapped. A counter-offer — the bank will lend, on different terms — has no equivalent in our vocabulary, and calling it "approved with conditions" would send a desk down the wrong path. It is recorded with the lender's own word visible and a note to look at the deal by hand.

Search before you start a credit application — and take one from a business

creditdealershipcontacts

Until today there was exactly one way to start a credit application: open a customer you already had and press the button. A walk-in you had never met meant typing them into the CRM first, and if they were already in there under a slightly different name, the store now had two of them — with the deals, the message history and the previous application on the one nobody was looking at.

The gate

Dealership → Credit review now opens with Start an application, and the first thing it does is search.

Pick Individual or Business, type the name, press Search. You get back everyone who might be them, with enough beside each one to tell them apart: phone, email, town, and how many credit applications they already have and when the last one was. That last column is usually the answer — two Robert Smiths are two people, and only the one with an application from March is the Robert Smith standing in the showroom.

Then either use this customer, or say none of these and start a new record.

"None of these" is still checked

Saying none of these does not create a duplicate on its own. Behind the button, the phone number and email you typed run through the same matching every web lead and every website application already uses — last ten digits, so formatting differences do not matter. If they hit an existing customer, the application goes on that record and the screen tells you so, rather than quietly doing the right thing somewhere you were not looking.

This is why a phone number or an email is required to start a new one. Without either, there is nothing to tell this customer from the next person with the same name, and "create" would mean "create" every single time.

Business applicants

Choose Business and the application changes shape. The borrower is the company:

  • Legal business name — what goes on the contract.
  • EIN, entered by the customer on their own link.
  • Type of business — LLC, corporation, S corporation, sole proprietorship, partnership, non-profit or trust. A list, not a text box, so your applications do not carry three spellings of "LLC".
  • Time in business, in years and months.
  • The owner or officer who signs, with their own name, SSN and income — the lender checks their personal credit as guarantor.

A second signer on a business application is recorded as an additional guarantor, not a co-applicant. They are different things: an adverse-action notice is owed to an applicant and not to a guarantor.

The customer's link, the review screen and the printed application all follow the choice. A sole trader buying a truck in their own name never sees an EIN box they have to work out they should ignore.

The EIN is treated like a Social Security number

Because it is one. An EIN is a taxpayer identification number, and a sole proprietor is entitled to use their own social as their business's — so the same nine digits can arrive in either box.

It is encrypted, it never appears on the credit review screen, and there is no "last four" anywhere. It prints on the dealer's copy of the application — the one your finance manager keys into a lender portal — and that print writes a line to the PII access log, exactly as printing an SSN already does. The customer's own printable copy leaves it as a blank line to fill in by hand.

A sole proprietor may not have one

We do not require an EIN from a sole proprietorship, because the IRS does not either. Their SSN is the business's taxpayer number, and demanding an EIN would have got a placeholder typed into the field. Every other entity type has to provide one before the application can be signed.

Screens with personal information now sign themselves out

securitycompliancecontactsdealership

A dealership computer sits on a sales floor, and it gets walked away from. Until today it could be walked away from with a credit application on screen — name, date of birth, social security number, driver's licence — and it would still be there an hour later for whoever wandered past the desk.

Four screens now sign themselves out when nobody has touched the machine for 30 minutes:

  • Contacts and any customer's record
  • Dealership → Credit — the credit application
  • Dealership → Documents and the deal jacket behind it
  • The documents inside a deal

You get two minutes' warning

At 30 minutes idle a box appears saying you are about to be signed out, with a countdown. Press Stay signed in and you carry straight on — the page behind the box never went anywhere, so a half-filled application is exactly as you left it, in the same box, with the same cursor.

The box also says the thing it would be dishonest not to say: anything you have typed and not saved will be lost. Two minutes is enough to press Save first.

Nothing else in the app logs you out

This is deliberately not an app-wide timeout. A manager can leave the dashboard, a report or the inventory list up all afternoon and nothing will happen — those screens do not have somebody's personal details on them, and being thrown out of a screen you were reading is its own kind of broken.

Typing counts. A wobbly desk does not

The clock measures time since you last clicked, typed, scrolled or tapped — not time since you opened the page. Somebody who has been working through an application for 45 minutes straight is never interrupted.

Moving the mouse is deliberately not enough on its own. On a sales floor a bumped desk or somebody leaning on the counter will nudge a cursor, and a machine that keeps itself signed in because the desk wobbled is not protecting anything.

Nor does the app keep itself alive: pages on this platform refresh their own data in the background every minute or two, and none of that counts as you being there.

Two screens open at once is fine

If you have a customer's record on one monitor and are working in another tab, the record does not expire underneath you. Working anywhere counts as working, and the timeout only ends the session when every window has gone quiet. When it does, every tab clears at the same moment rather than one of them sitting there still showing the customer.

Thirty minutes, and it is not adjustable

Thirty minutes is the number Dealertrack uses, so it is the one most people on a dealership floor already have a feel for. It is fixed on purpose — a timeout a store can set to eight hours is a timeout that has been switched off, and this is the kind of control that is only worth having if it is the same everywhere. If 30 minutes genuinely does not fit how your store works, tell us; that is a conversation worth having with a real example in it.