Release notes

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

Edit, sign and print deal documents in one place

dealershipdeal-deskdocumentse-sign

Printing a deal document used to hand you a flat PDF. A typo meant going back and regenerating the whole deal, and a signature meant printing, signing by hand and scanning it back in. Print / edit now opens a workspace instead: the fields on the left, a live preview of the document on the right.

What you can change

Text only: buyer name and address, vehicle year / make / model / trim / VIN, stock number, odometer, color, plate, trade-in details, dealer details, sale date, lienholder name and address on the forms that carry one, and the labels on fee and product lines.

Prices, fees, tax, rates, terms and totals are not editable here. Changing a number would mean recomputing tax, the amount financed and the finance disclosures, and an edit that left those out of step would put a wrong number on a contract. Change the deal in the desk and regenerate for that.

Contracts, the odometer statements, the Buyers Guide and the state forms can be corrected too, with a reminder to check with your lender or compliance advisor before changing a regulated form.

Buyer signature, no printing

On the documents a buyer signs (buyer's order, contract, Buyers Guide, As-Is, arbitration, We-Owe, damage disclosure, credit score disclosure, insurance agreement, payoff authorization and the two warranty waivers), the workspace has a Buyer signature box:

  • Buyer signs here opens the signing page on your screen. The buyer reads the document, types their name, draws their signature with a finger, stylus or mouse, and agrees.
  • Copy link to send gives you a link to text or email, and the buyer signs on their own phone.

The drawn signature is printed on the signature line of the PDF, with the signed date, so Download gives you a signed copy to upload for the lender — no print, sign and scan. Your lender decides whether an electronic signature is acceptable on the contract itself, so check that with them first.

What stays safe

  • The original is kept. Edits are a separate, versioned layer. Reset to original is one click, and the history shows who changed what and when.
  • Edited copies are marked. Every page carries "Edited copy · v3 · date" in the footer so it can't be passed off as the original.
  • Signed documents are locked. To change one, use Void and create a corrected copy: the signed original stays on file and a new draft starts from what the customer saw.
  • Signing links follow the edit. Saving an edit turns off any signing link already sent for that document, so a customer can't sign something that changed underneath them. What the customer sees and signs is the edited version, and the signature is bound to exactly that.
  • Every edit, print and download is logged with who did it and when.

Also fixed

Signed deal documents printed the signer's IP address as a long encrypted code. They now show the address.

The workspace is switched on per dealership. If it isn't on for yours, Print works exactly as before.

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.