AI & Automation

Querying PMS Data in Plain English: Building on the Natural Language API

"Show me next week’s unconfirmed appointments." Your users think in questions like that. Behind the scenes it is a join across three tables and a status lookup. The Natural Language Query API bridges the two.

CRMBridge Team · July 9, 2026 · 8 min read
"show me unconfirmed appts next week" user asks NL Engine interprets SELECT ... WHERE date status = ? structured query rows back

Your users think in questions, not schemas

Watch a front-desk coordinator work and you notice something: they never think in tables. They think in questions. "Who’s overdue for a recall?" "Which of tomorrow’s patients still owes a balance?" "Show me the treatment plans we presented last month that nobody accepted." Every one of those is a perfectly natural sentence and a genuinely annoying query — a join across appointments, patients, and transactions, with a date window and a status filter bolted on.

The traditional way to serve those questions is to build a screen for each one. A "recall due" report. An "unconfirmed appointments" view. An "outstanding balances" filter. Then the next question arrives, and you build another screen. There is no end to the questions, so there is no end to the screens. You are effectively hand-compiling a query language one form at a time.

The Natural Language Query API collapses that. Instead of anticipating every question and shipping a UI for it, you give your users a text box. They type the question the way they’d say it out loud, and CRMBridge translates it into a structured query against live PMS data. The endless report backlog turns into one endpoint.

The endpoint

One route does the work: POST /NaturalLanguageQuery. Like the rest of the CRMBridge API, it authenticates with three headers that scope the call to a single practice and location:

Required headers

BusinessID, APIToken, and LocationId. These identify the caller and pin the query to one tenant and one location. There is no way to reach across them.

The body carries the question and the paging controls:

  • Query — the plain-English string, up to 500 characters. This is the question, exactly as your user would phrase it.
  • CRMPracticeId — optional. Narrows the query to a specific practice record when the location maps to more than one.
  • Skip and Take — standard pagination. Take caps the page size; Skip offsets into the result set.

Out of the box it can answer questions across four entities: Patients, Appointments, Transactions, and Treatment Plans. Those four cover the overwhelming majority of "can you just tell me…" questions a practice asks in a day.

The response shape

The response is designed so you can build a trustworthy UI on top of it — not just the rows, but everything you need to tell the user how the rows were found. Five fields matter:

Interpretation

A plain-English restatement of how the AI understood the request — the entity it queried, the filters it applied, the date window it chose. This is the single most useful field. Show it to the user so they can confirm the machine understood the question before they trust the answer.

Data

The rows themselves, as structured records for the entity that was queried. Render them in a table, feed them to a chart, or pipe them into the next step of a workflow.

Count and TotalCount

Count is how many rows came back in this page; TotalCount is how many matched overall. The pair drives your pagination controls — "showing 25 of 214" — and tells you whether to fetch another page with Skip.

Confidence

One of high, medium, or low — how sure the model is that its interpretation matches the intent. Branch your UI on this. High: show the answer. Medium or low: show the interpretation prominently and invite the user to confirm or rephrase.

A note on safety — this is not "run arbitrary SQL"

Two guardrails make this endpoint safe to put in front of end users. First, tenant isolation: every query is scoped to the caller’s Business and Location by the same headers that authenticate it. There is no query phrasing — however clever — that reaches another practice’s data.

Second, no free-form SQL execution. The model does not write and run raw SQL against your database. It translates the question into a structured, parameterized query over a known set of entities and fields. User input becomes bound parameters, never concatenated SQL, which closes the door on injection.

And it is read-only. Natural Language Query answers questions; it never inserts, updates, or deletes. "Show me" is in scope. "Cancel all of tomorrow’s appointments" is not.

A worked example

Suppose your front-desk copilot wants a recall-and-retention list: patients with a birthday this month who haven’t been in for a year. That is a genuinely fiddly query to write by hand. Here it is a sentence:

curl -X POST https://api.crmbridge.ai/NaturalLanguageQuery \
  -H "BusinessID: 4821" \
  -H "APIToken: sk_live_9f2c8a71b40e" \
  -H "LocationId: 17" \
  -H "Content-Type: application/json" \
  -d '{
        "Query": "patients with a birthday this month who haven'\''t been seen in a year",
        "Take": 25
      }'

And the response — note how Interpretation restates the intent, Confidence is high, and the paging counts let you keep going:

{
  "Interpretation": "Patients whose date of birth falls in the current month (July) and whose most recent appointment was more than 12 months ago.",
  "Confidence": "high",
  "Count": 25,
  "TotalCount": 63,
  "Data": [
    {
      "PatientId": 90412,
      "FirstName": "Marisol",
      "LastName": "Reyes",
      "DateOfBirth": "1979-07-22",
      "LastVisit": "2025-03-14"
    },
    {
      "PatientId": 88771,
      "FirstName": "Devon",
      "LastName": "Okafor",
      "DateOfBirth": "1965-07-03",
      "LastVisit": "2025-01-28"
    }
  ]
}

Sixty-three matches, twenty-five on this page. Your copilot shows the interpretation ("here’s what I looked for"), renders the twenty-five rows, and offers a "load more" button that fires the same call with Skip: 25. No report was built. No screen was designed. A coordinator typed a sentence.

Best practices for building on it

A few patterns make the difference between a demo and a feature people rely on:

Always surface the Interpretation.

Never show rows without also showing what the system thought you asked for. It costs one line of UI and it is the difference between a user trusting the answer and a user quietly wondering whether they got the right one.

Degrade gracefully on medium and low confidence.

On high, lead with the answer. On medium or low, put the interpretation front and center and ask the user to confirm it or rephrase. A confident wrong answer is worse than an honest "did you mean…?"

Paginate with Skip and Take.

Pick a sensible Take, watch TotalCount, and page with Skip. Don’t ask for everything at once; a "who’s overdue?" query can match thousands of patients.

Keep queries under 500 characters — and cache nothing sensitive.

The Query field caps at 500 characters, which is plenty for a real question; validate before you send. And because responses contain PHI, don’t cache them anywhere they’d outlive the session or escape the tenant boundary.

What this unlocks

Once "ask a question, get live PMS data" is a single call, whole product categories open up that used to mean months of report-building:

A front-desk copilot

"Who’s overdue for recall?" "Which of today’s patients has an unpaid balance?" "What’s open on Thursday afternoon?" The coordinator types; the copilot answers from live data. No training on where each report lives, because there are no reports — just a box.

Embedded analytics

Drop a query bar into your existing dashboard. Users explore their own numbers — production by provider, accepted-vs-presented treatment plans, aging balances — without you pre-building every cut. The rows come back structured, ready to chart.

A patient-facing chatbot

Scoped carefully, a patient chatbot can answer "when’s my next appointment?" or "do I owe anything?" against real data instead of canned responses — while tenant isolation and read-only access keep the blast radius small.

Voice assistants

Because the input is already natural language, a speech-to-text front end drops straight in. A clinician asks the room a question on the way between operatories and hears the answer back. The API doesn’t care whether the sentence was typed or spoken.

The text box beats the query builder

The old answer to a new question was "we’d need to build a report for that." The Natural Language Query API replaces that sentence with a text box. Your users bring the questions — all of them, including the ones you never anticipated — and CRMBridge turns each one into a safe, scoped, structured query against live practice data. You stop building screens and start shipping answers.

Give your users a text box, not a query builder.

The Natural Language Query API gives your app plain-English access to live PMS data — Patients, Appointments, Transactions, and Treatment Plans — across 35+ practice management systems, with tenant isolation and read-only safety built in.