Repository navigation
Releases: Elegant-IT-Limited/attendra
Release list
Attendra 0.8.0
Attendra 0.8.0 is the veterinary front desk, a hosted service around the open-source engine, and a week of work on how calls sound. It is the version behind the private beta at getattendra.com. Real phone lines on production and the first beta clinics come next, in 0.9.
Calls that sound like a front desk
Tested with a model playing the caller and a judge scoring every call: the live run went from 48 of 56 scenarios to 76 of 78, with 22 harder scenarios added on the way.
- The voice lets the caller finish. A pause to think is not the end of a turn.
- The caller is looked up with what they already said, before anything is asked. A new detail, such as another phone number, is looked up at once.
- One question at a time, never the same one twice, and free times before questions.
- No question about which vet or doctor: the clinic's booking rules choose, and a caller can still name one.
- "Anything after three?" gets times from 3:00 (
find_slotstakesfrom_time). A closed day, such as a holiday, gets the next open times. - Ages and birthdays as owners say them ("about two", "she was born on the fifteenth of January"), and a rough age is enough for a new pet.
- A caller who has to go is let go with a goodbye. Asked whether it is a person, the assistant says it is an AI assistant.
The veterinary front desk
- Refill requests a vet approves before the owner gets a "ready to pick up" text, and records requests for boarding, groomers and other clinics.
- The emergency hospital (several, with their hours) and the after-hours choice in Settings: take requests for the morning, or keep booking.
- Each pet's kind of animal on its page, and vets offered only for the animals they see.
Running a clinic
- Locations: each with its own number, hours, vets and hospital, one login for the team.
- Your own fields and lists on pets, vets and requests; urgent requests and due days.
- Booking rules: the pet's usual vet first, then the earliest time, with the fewest visits that day or your own order. Special days, half days and part-day time off.
- Visit reminders with consent and quiet hours, and texts during a call (directions, hours, the hospital, your links), only after a yes.
- A rule for abusive callers, drag and drop for reordering, and a plan meter everyone on the team can see.
Platform
- GPT Realtime as a second voice engine, on the same backend through one tool,
ask_backend; GPT-Live stays the default. - Accounts: forgot password, Your account, optional two-step sign-in, and an idle sign-out a deployment chooses.
- Integrations: signed webhooks (8 events) and an MCP server for AI agents, also on a hosted service at
/mcp, with scoped keys on Settings > API keys. - For hosting: provisioning endpoints, including a calls check for forwarding.
- The dashboard wears the website's brand: warm neutrals, slate instead of teal, Geist and the Attendra mark.
Quality
About 950 tests and 78 scripted call scenarios run on every pull request, with live runs against the real models before each batch of call changes.
Upgrading
From 0.7.0, start the new version: Compose's migrate service applies migrations 0025 to 0035 on its own (outside Compose, pnpm db:migrate). If you call the API or listen to webhooks, read API changes for integrators in CHANGELOG.md first.
The full list of changes is in CHANGELOG.md.
Attendra 0.7.0: the veterinary pack
Attendra 0.7.0 adds a second industry: veterinary clinics. Same engine, same safety rules, a different front desk.
Pets, found by their owner
At a clinic on the veterinary pack (industry: vet), the patient is a pet. The assistant finds it by the owner's full name, the pet's name and the phone on file, with the same rules as for a person: three tries, the same answer whichever detail was wrong, and two pets with the same name on one number go to staff. An owner with several pets moves from one to the next on the same call.
A new pet is added with its owner as the guardian, what kind of animal it is, and its birthday or age. "About eight months" becomes an estimated date of birth, and the front desk is asked to check every pet the assistant adds. The dashboard says Pets and Veterinarians.
Animal emergencies
A phrase list in English and Spanish, checked on every caller fragment before the engine's own: toxins and swallowed objects (chocolate, antifreeze, rat poison, a sock), breathing trouble, being hit by a car, collapse and seizures, bloat, a cat that cannot urinate, heatstroke and difficult births. The caller is sent to the clinic's chosen emergency hospital, with its address and phone, or to the nearest 24-hour emergency vet, and a person who is hurt or in danger is told to call the emergency number. No first-aid advice, ever. Staff cannot end the call until the hospital's name has been said.
The person on the phone is still covered: chest pain at a vet clinic gets the 911 script, and self-harm language always comes first.
After-hours requests
A new afterHours setting for every clinic: book as before, or requests, where nothing is booked or cancelled while the clinic is closed and the caller's visit becomes a request for the team in the morning.
Also in this release
- "Should I give him some of my ibuprofen" and "is that serious" are refused like "should I take", for clinics and veterinary clinics alike.
- The Test call page says when the browser did not report echo cancellation, instead of assuming it is on.
- A demo veterinary clinic, Riverbend Animal Hospital, with four pets and its own demo login, and 10 call scenarios for it.
- PGlite 0.5.10, pglite-pgvector 0.0.11, Playwright 1.64.1.
Upgrading
Migration 0024 adds the encrypted kind of animal to patients. Nothing else to run.
693 tests and 39 call scenarios pass.
Attendra is built and maintained by Elegant IT Limited.
Attendra 0.6.0: industry packs
Attendra 0.6.0 separates the engine from the trade it works in, so the same receptionist can serve more than medical practices.
Industry packs
Booking, the identity check, the emergency guardrail, requests, the clinic's knowledge, live calls and the audit log are the same for every business. What depends on the trade now lives in an industry pack: what the business, the people who are booked and the people who can be booked are called, and the lines of the conversation prompt that only make sense in that trade.
Each account picks its pack in settings (industry, default clinic). Medical clinics are the first pack, and their conversation prompt is unchanged word for word. Database tables and API fields keep their names, so there are no migrations. The dashboard menu, the Patients and Doctors pages, Settings and the command palette use the pack's words. docs/industries.md explains how to add one.
The rules that keep callers safe stay in the engine and apply to every pack: nothing is booked without a read-back and a clear yes, records are never confirmed to an unverified caller, and the emergency guardrail cannot be turned off.
Test calls check the microphone
After the microphone starts, the Test call page reads what the browser actually applied and warns when echo cancellation or noise suppression is off, so a laptop-speaker test does not end with the assistant answering its own voice.
At most five new patients per phone number a day
The assistant already added at most three new patients on one call. Registering now also counts patients added on calls from the same number in the last 24 hours, and past five it offers a callback instead. Someone already on file is still found by the identity check.
Doctors' names in other languages
The doctor panel has an "In Spanish" field (one per extra language the clinic speaks), so the assistant says a doctor's name the way Spanish-speaking callers say it.
The latest stack
Next 16.4, the OpenAI SDK 7.33 (with the new GPT-Live voice "Shida" in Settings), radix-ui 1.8, pg-boss 12.38, Twilio 6.2, Playwright 1.64, and the latest patch of everything else. TypeScript stays on 6.0 until typescript-eslint supports 7.
Upgrading
Nothing to run. No migrations in this release.
630 tests and 29 call scenarios pass.
Attendra is built and maintained by Elegant IT Limited.
Attendra 0.5.2: no hanging up mid-request, follow-up requests
Attendra 0.5.2 fixes what a browser test call showed: a parent booking for a child was asked for the same details again and again, waited half a minute in silence, and was then hung up on mid-sentence.
No hanging up on a caller
Ending a call now takes two steps, like a front desk: the assistant asks "Is there anything else I can help you with?", and ends the call only after the caller says no or goodbye. "I'm done" at the end of a phone number no longer ends the call. A frustrated caller whose request is unfinished hears what the assistant can still do, or is offered a callback. When the call does end, the hang-up waits until the assistant has finished speaking, so a goodbye is never cut off.
Unfinished calls become requests
A call that ends with the caller's request unfinished (nothing booked, an error, an upset caller) now opens a "Follow up" request on the Requests page, with the reason and a suggested next step, linked to the call. Staff no longer have to spot it on the Calls page. Closing the request marks the call reviewed.
Other languages
A caller speaking a language the clinic does not offer is told kindly, in one sentence, that the assistant can only help in English (or the clinic's languages), and is asked to carry on in it or offered a callback.
Dates of birth
When a date of birth cannot exist, the assistant now says why. "29 February 2025" gets "February 29 is not a date in 2025, which is not a leap year", and the caller is asked to check the date only. The name and phone they already gave are kept, and a date that cannot exist does not count as a failed identity check.
No asking twice
The assistant passes what the caller said to the backend instead of judging a date itself, so the same checks and the same wording apply every time. It never asks again for a detail the caller already gave on the call. Someone who says they are new is still looked up first, with the details they gave.
No long silences
When a request takes longer than 7 seconds, the caller hears once that the assistant is still checking.
Test calls
The Test call page asks for headphones in a quiet room. From laptop speakers the assistant can hear itself, and background voices are taken for the caller.
Migration 0023 adds the new request type on its own. 620 tests and 29 call scenarios pass.
Attendra is built and maintained by Elegant IT Limited.
Attendra 0.5.1: gender, and doctors by specialty
Attendra 0.5.1 adds gender for patients and doctors, and lets callers and staff find doctors by specialty.
Patients
Every patient now has a gender: female, male, other, or prefers not to say. It is required when a patient is added or changed, on the form, in the CSV import, and when the assistant adds a new patient on a call. The assistant asks and never guesses. Gender is stored encrypted, like every other detail about a person. Patients added before 0.5.1 keep an empty value until the front desk fills it in, and their record shows that it is missing.
Doctors
Each doctor has a gender too. A caller who asks for a female or a male doctor is offered only those doctors, and is told plainly when there is none for that visit.
Doctors by specialty
When a caller wants a visit and has not named a doctor, the assistant asks once whether they would like a particular doctor or a particular kind of doctor. It matches the answer, such as pediatrics, a pediatrician or women's health, to the specialties and categories the clinic has listed, suggests those doctors by name and offers their open times. When the clinic has no such doctor, it says so and lists what the clinic does have. It never decides from symptoms what kind of doctor someone needs.
On the Doctors page, staff can filter by specialty and by what doctors see people for, and sort by name or by specialty. The Schedule's provider list shows each doctor's specialty.
Small fixes
The Doctors page shows each day's hours on its own line, category badges keep their size, and the hour fields in the edit panel show the whole time.
Upgrading
Migration 0022 adds one column and runs on its own. POST /patients, PATCH /patients/:id and the doctor endpoints now require gender, and find_slots takes an optional specialty. The details are in the CHANGELOG.
612 tests and 29 call scenarios pass.
Attendra is built and maintained by Elegant IT Limited.
Attendra 0.5.0: doctors, families and a dashboard that keeps up
Attendra 0.5.0 comes straight out of the first test calls. Callers asked which doctors the clinic has and who sees children, and the assistant could not say. A new patient could not get past the identity check. A parent calling for a child had nowhere to go. And the front desk had to refresh the page to see a request that had just come in. All of that is fixed.
Doctors
Each doctor now has a specialty, what they see people for, the ages they see, whether they take new patients, their weekly hours and their days off. They live on a new Doctors page, where managers add, change and remove them, or import a whole list from a CSV template.
The assistant tells any caller who works at the clinic and who is free on Monday, without asking who they are first. It reads the clinic again before every request, so a doctor added in the middle of the day, or a day off, counts on calls already under way.
Patients, families and new callers
A patient is now one person by name, date of birth and phone number together. Two people with the same name and birthday are told apart by their phone, and the same person can never be stored twice. Phones are compared on their last nine digits, so a number written with or without its country code is the same number.
A family shares a phone. A parent books for each child on that number, one after the other on the same call, and every child under 18 has a parent or guardian on file. Doctors are offered by the patient's age, so a pediatrician is offered for a child and a doctor for adults is not.
Someone new to the clinic is added on the call, books a new patient visit with a doctor who takes new patients, and lands on the Requests page for the front desk to check. It cannot be used to get round the identity check's three tries, and until the front desk confirms the new patient, booking texts only go to the number they are calling from.
Managers can import their patient list from a CSV template. Every row is checked before anything is saved, and the same file can be uploaded twice without adding anyone twice.
A dashboard that keeps up
Every screen now updates as the clinic changes, with no refresh: a request the assistant took, a booking, a new patient, a finished call, a doctor's new hours. Each search answers as you type, from the first letter or the first few digits of a phone number. Requests can be searched and narrowed to the days they came in. The newest come first, and the schedule keeps cancellations as a history of their own, sorted by when the visit was due or when it was cancelled.
Under the hood
Node 24, pnpm 12, TypeScript 6, Next 16.3, NestJS 12.1, Postgres 18 with pgvector 0.8.7, and every other dependency at its latest. 606 tests and 29 call scenarios pass.
Upgrading
Compose moves to Postgres 18 on a new volume, two migrations run on their own, and one command recomputes the patient hashes. The steps are in docs/self-hosting.md, and every API change is in the CHANGELOG.
Attendra is built and maintained by Elegant IT Limited.
Attendra 0.4.1: the audit release
A correctness release. We audited 0.4.0 line by line and fixed everything we found. There are no new features.
Calls and bookings
- The emergency transfer to the on-call number is kept when a caller says "emergency" before the symptom.
- Slot search offers the earliest time across all providers.
- Names with letters such as ø, ł or ß now verify.
- Two cancels at the same moment can't both succeed, and the phone path checks for overlapping visits.
- When the assistant promises a callback, it creates one.
Front desk
- A visit you just cancelled stays on the Schedule, marked. The header counts the cancelled visits it hides.
- The call page says "Since cancelled" or "Since moved" for each booking.
- The Calls list shows the assistant's steps in call order, and how each confirmation ended.
- Pages that need a permission show a clear empty state, instead of an error.
- The live call page recovers when its stream drops.
Webhooks, knowledge and data
- Webhook deliveries keep their own retry policy, so an endpoint that keeps failing is switched off as documented.
- A partial update to an endpoint keeps its description.
- A document is indexed again when the embedding model changes or its indexing stalls.
- Same-clinic foreign keys everywhere, with migration 0017 checking existing data first.
- Webhook data follows the clinic's retention days.
- A call is audited once when it opens and once when it closes, with counts. Repeat views of requests and transcripts are deduplicated.
Docs and demo
- New README screenshots.
- A complete upgrade note in
docs/self-hosting.md, covering the backup, migrations 0017 to 0019 and a one-timedb:rehash-lookups. - The demo's calls now run at their own time, so each transcript, its call date and its booking agree.
API changes for integrators
invalid_requestis always 422.- Create routes return 201.
Upgrading from 0.4.0: follow "Upgrading to v0.4.1" in docs/self-hosting.md.
- Back up.
- Start the new version. Migrations 0017 to 0019 run on their own.
- Run
db:rehash-lookupsonce.
The full list is in the CHANGELOG.
Attendra 0.4.0: the AI layer
Staff can now watch the assistant work live and coach it, every call gets a summary, the assistant answers from the clinic's own documents, and a Quality page shows how well it performs. There is a new design system across the whole dashboard, in light and dark.
What is new
- Live calls. Watch a call as it happens: captions, every step the assistant takes, whether the caller is verified, and the read-back it is waiting on. Staff can send the assistant a private note, take the call over (phone calls), or end it. Notes can never skip the identity, read-back or yes checks, and during an emergency the script always comes first.
- Call summaries. A background worker writes a short summary for every call, with intent, mood, a review flag and a suggested follow-up. Fixed rules always flag calls that need staff, whatever the model says.
- Clinic knowledge. Upload policies, insurance lists and visit preparation. The assistant answers only from them, with citations, and still refuses anything medical.
- Quality. Week by week: calls handled without staff, booking success, why the assistant said no, transfers, after-hours calls, and cost per call and per booking.
pnpm eval --live --judgescores calls with a judge model, andpnpm simruns simulated callers. - The clinic's own assistant. Each clinic names its assistant ("Hi, I'm Maya, Maple Street's AI assistant"), in English and Spanish. The AI disclosure is always enforced, and the emergency number follows the clinic's country.
- Webhooks. Signed Standard Webhooks events for n8n, Zapier, Make or your own systems, with retries, a delivery log and an SSRF guard. Patient ids are left out unless an endpoint asks for them.
- MCP server. Other AI agents can read the schedule and requests and close requests with scoped, expiring, per-clinic API keys. No tool can book or cancel.
- Design system. One set of tokens, a full dark mode, a Cmd+K command palette, keyboard shortcuts, undo, a phone layout, and WCAG 2.2 AA checked in every e2e run.
Security and privacy
- A yes counts only in the languages the clinic offers, and any hedge in any language blocks it.
- Medical questions are refused on the caller's own words, not only the model's.
- Every live watch, coaching note length, staff action, knowledge upload, key use and webhook change is audited.
- API keys stop working when their creator loses the role. Uploads are size-limited per route, PDFs are read in a sandboxed worker thread, and webhook deliveries have a hard deadline.
- No keys ship with Attendra: each deployment brings its own OpenAI and Twilio keys in its own
.env.
Try it
pnpm install
pnpm demo # then open http://localhost:3000Click Front desk or Practice manager to sign in. Everything is synthetic. On Test call, Watch a simulated call shows the live view with no audio and no OpenAI credit. Add OPENAI_API_KEY= to a .env at the repo root to talk to the assistant through your microphone.
Upgrading
- Run
pnpm db:migratefor the new tables (summaries, knowledge, webhooks, API keys) and their row-level security. - Docker Compose now uses
pgvector/pgvector:pg16and adds aworkerservice. See docs/self-hosting.md. - New optional settings are listed in
.env.example. - MCP clients connect with a server URL and an API key only. See docs/mcp.md.
Full list of changes: CHANGELOG.md
Attendra 0.3.0: the working front desk
The dashboard becomes a front desk a clinic can run its day on, and you can talk to the receptionist from your browser with nothing but an OpenAI key.
What is new
- Test calls from the browser. A Test call page talks to the clinic's receptionist through your microphone over WebRTC, with the live settings and the same tools and guardrails as a phone call. No phone number or Twilio account needed. See docs/test-calls.md.
- Today. The new home screen: what needs someone now, today's appointments per provider, what the assistant did today and this week, and the latest calls.
- Schedule. Day and week views with a column per provider, who booked each visit (the assistant or a named staff member), and booking, moving and cancelling at the desk under the same rules the assistant follows.
- Patients. Search by name, date of birth or phone, a profile with appointments, calls and requests, and add or edit patients the assistant can then verify.
- Requests. What was called Tasks: refills, callbacks and voicemails with notes, assignment and an outcome when closed.
- Calls. Filters, patient search, and the verified caller's name.
- Team. Add people with a one-time temporary password, reset passwords, change roles, remove people. There is always an owner.
Security and privacy
- A temporary password works once and for 72 hours, and the new member chooses their own password before anything else, two-step setup included.
- Every patient view, search result and team change is audited in the same transaction as the read or write.
- The database itself keeps records linked only within one clinic.
- Test calls end after 5 minutes, a clinic can have two open at once, and they never send texts.
- No keys ship with Attendra. Each deployment brings its own OpenAI and Twilio keys in its own
.env, which is never committed.
Fixed after the first live test call
- A clear "yeah" to a read-back is now counted even when the assistant reads the booking back in the same breath as "let me book that".
- A cough or breath marked in the transcript no longer cancels the caller's yes.
- The assistant knows today's date and the next seven days of hours, so "next week" and "are you open tomorrow?" work.
Try it
pnpm install
pnpm demo # then open http://localhost:3000Sign in as frontdesk@maple-demo.test or manager@maple-demo.test with the password attendra-demo-password. Everything is synthetic. Add OPENAI_API_KEY= to a .env at the repo root to turn on test calls.
Upgrading
Run pnpm db:migrate. Migrations 0003 to 0008 add the call channel, staff scheduling, the call to patient link, request notes, password changes and same-clinic foreign keys. The voice service and the API take the new optional settings VOICE_URL, VOICE_INTERNAL_TOKEN and BROWSER_CALL_MAX_SECONDS; see .env.example.
Full list of changes: CHANGELOG.md
Attendra 0.2.0: the front desk
The staff side of Attendra. Everything the assistant did on a call can now be read, worked and audited by the clinic's own people.
Try it in one command
pnpm install && pnpm demo # then open http://localhost:3000No keys and no Docker. It starts the API on an in-memory Postgres, plays every call scenario through the real agent as a week of calls, and opens the dashboard. Sign in as manager@maple-demo.test or frontdesk@maple-demo.test with the password attendra-demo-password. Everything in it is synthetic.
What's new
- Dashboard (
apps/web, Next.js):- the call list with outcomes and emergency flags
- each call's transcript and every tool step
- the refill and callback queue with claim, release and done
- clinic settings, validated with the same rules the voice service uses
- the audit log
- API (
apps/api, NestJS on Fastify, OpenAPI at/api/docs). Four roles: owner, admin, staff and viewer. A clinic you don't belong to answers 404. Every transcript or task view writes its audit row in the same transaction as the read. - Sign-in with Better Auth. Two-factor (TOTP) is required before any clinic data is shown. There is no public sign-up; owners add people with
pnpm add-member. Sessions last 12 hours, and the screen signs out after 15 idle minutes. - Demo mode for
pnpm demoand Docker Compose. A deployed demo takes its password fromATTENDRA_DEMO_PASSWORDand can't change transfer numbers. - docs/live-call.md: a small server to a real phone number the demo clinic answers.
- Browser tests (Playwright) in CI, next to the 140 unit and integration tests and the 15 call scenarios.
Upgrading from 0.1.x
- Run
pnpm installandpnpm db:migrate. Migration 0002 adds the staff and auth tables. - Set
BETTER_AUTH_SECRETandPUBLIC_URLin.env. - Add yourself:
ATTENDRA_NEW_PASSWORD='...' pnpm add-member --email you@clinic.example --name "Your Name" --org <org id> --role owner. - With Compose, the voice service now starts only with
--profile voice.
Why the dashboard signs people in the way it does: decision 0006. Full notes: CHANGELOG.md.
