Inspiration

My partner and I live with disabilities caused by rare diseases, and my partner is a wheelchair user. For us, deciding whether to visit a cafe, clinic, cinema, or hotel often starts with questions that the venue's website does not answer.

“Wheelchair accessible” is rarely enough. How many steps are at the entrance? Is the accessible toilet on the same floor and kept unlocked? Is the lift working today? Can a companion enter the accessible toilet? A single missing detail can turn an ordinary outing into a wasted journey.

The information usually exists, but only with the person currently working at the venue. Getting it means making the same tiring phone calls again and again. That work falls on the person who may have the least energy to spare.

I built Is it accessible? to do that phone work while keeping the questions personal. It does not ask whether a place is “accessible” in the abstract. It asks whether that place will work for this person, on this visit.

What it does

The user chooses up to 12 items from a catalogue of 30 accessibility needs across mobility, vision, hearing, sensory, cognitive, and support requirements. Each need can be marked as essential or nice to have, and the user can add practical context such as the width of their wheelchair.

They then choose a venue through Google Places or enter its name and number manually. Before anything happens, the application shows exactly which venue will be called, what will be asked, and what information will and will not be shared.

CALL-E phones the venue and asks concrete questions. Instead of “Is your entrance accessible?”, it asks how many steps there are and whether an alternative entrance exists. Instead of “Do you have an accessible toilet?”, it asks where it is and whether it is kept unlocked. If an answer is vague, the agent asks one specific follow-up without treating the call as an inspection or pressuring the staff member.

The result is a report for that person's needs:

  • Every need receives a Yes, No, Partly, or Unknown finding.
  • A positive finding must include a direct quote from the call or it is changed to Unknown.
  • The report shows how confident the extracted answer was when CALL-E provides a confidence level.
  • Essential needs determine the overall result. A venue cannot average its way past a barrier that makes the visit impossible.
  • When the venue's answer conflicts with a Google accessibility field, the contradiction is shown beside the supporting quote.
  • Several venues can be called in one batch and ranked by how well they meet the same profile.

Real phone tasks can outlive a browser session, so the application returns a reference as soon as CALL-E accepts the task. A webhook records the completed result, Supabase Realtime updates an open results page, and an optional email sends a private link back to the report. The user can close the page and return later, or check manually if a live update is missed.

The same workflow is available through a command-line interface and a portable CALL-E skill. Practice reports exercise the complete profile, schema, and reporting flow without calling anyone or spending a credit.

How we built it

The core is a TypeScript library shared by the web application, CLI, and portable skill. A selected accessibility profile is transformed into two things at runtime: a detailed CALL-E goal and a matching per-recipient JSON result schema. The goal controls how the conversation is conducted; the schema gives every selected need a stable place for its verdict, quote, confidence, and notes.

I used the CALL-E Developer API because recipient result schemas are essential here. Parsing a free-form call summary would reintroduce the guessing that the application is designed to remove. For comparisons, multiple venues are recipients in one CALL-E task, which produces separate structured results while preserving one consistent set of questions.

The reporting layer does not display the structured result blindly. It applies domain rules before a claim reaches the user. An affirmative answer without a quote becomes Unknown. An essential Yes that CALL-E itself marked below high confidence also becomes Unknown. A barrier followed by an unverified workaround is capped at Partly. Failed calls are classified carefully so a service-side routing failure is never described as the venue refusing to answer.

Google Places provides venue selection, international phone numbers, and four published accessibility fields. I compare only explicit boolean claims with clear Yes or No findings from the call. Missing Google data remains missing, and an Unknown phone answer is never presented as a contradiction.

The web application uses Next.js and React. API keys remain server-side. Supabase provides authentication, owner-only row access, call persistence, and Realtime updates. CALL-E webhooks trigger a Supabase Edge Function that sends a minimal ZeptoMail notification containing a link rather than sensitive findings. Stable idempotency keys make network retries safe, while an explicit new attempt is required to ring a venue again.

I also packaged the workflow as a self-contained skill and submitted it to CALL-E's public Awesome Phone Call Agents repository in PR #496. It runs practice checks with Node.js alone and loads the CALL-E SDK only for real or resumed calls.

Built for accessibility

The people most likely to use this application should not have to fight the application itself. I treated accessibility as a build constraint from the beginning. WCAG 2.2 Level AA, the latest finalized WCAG Recommendation, is both the target and the current documented conformance level.

Playwright and axe-core scan every major screen against WCAG 2.0 A and AA, WCAG 2.1 A and AA, and WCAG 2.2 AA rules in CI. The coverage includes the need picker, call confirmation, waiting state, and completed report. Automated tests also exercise the flow with a keyboard and verify that sign-in still works with JavaScript disabled. I manually reviewed contrast, focus order, and error announcements in both light and dark themes.

The interface uses semantic HTML and native controls. Every input has a real label. A skip link and visible focus indicators support keyboard navigation. Controls meet the 44-pixel WCAG 2.2 target size, reduced-motion preferences are respected, and layouts tolerate zoom and larger text. Progress appears in polite live regions, and focus moves to a new waiting state or report so a screen-reader user is not left at a button that disappeared.

Colour never carries a result by itself. Every status is written in words, including Yes, No, Partly, Unknown, and the overall venue verdict. Errors are announced as well as displayed, and they explain how to fix the problem.

Testing with NVDA, JAWS, VoiceOver, and a broader group of disabled users is still needed, and it is one of the most important next steps.

Challenges we ran into

The hardest problem was not placing a call. It was deciding when an extracted answer was safe enough to influence a real journey.

In one live call, venue staff said there were steps at the entrance and described a ramp, but the structured result still reported a high-confidence Yes for step-free entry. A quote proved that words had been spoken, but did not prove that the verdict represented them correctly. That failure led me to add rules at three levels: questions ask for falsifiable details, schema descriptions define how barriers affect verdicts, and the reporting layer withdraws claims that do not have enough evidence.

The second challenge was time. The two end-to-end venue calls I measured returned after 74 and 119 minutes. A normal request-and-response page was therefore the wrong product shape. I separated placing a call from reading its result, stored a reference before the request could be interrupted, added webhook and Realtime delivery, and kept a manual resume path as a fallback.

Retries were another phone-specific problem. Retrying an ordinary API request is harmless; retrying a phone request can disturb the same business twice and waste limited credits. The solution combines deterministic references and idempotency keys for transport retries with a separate, explicit attempt token when the user really intends to call again.

Finally, failures needed careful language. “The venue did not answer” is unfair when the calling service never placed the call. The report distinguishes a confirmed no-answer from a service-side failure and from a call whose state is still uncertain.

Accomplishments that we're proud of

I am proud that this became a complete product rather than a phone-call demonstration. It has an accessible web interface, a CLI, a reusable skill, structured multi-venue calls, resumable results, private notifications, and a production deployment.

The part I care about most is the trust model. The application would rather say “I don't know” than turn a weak extraction into a green tick. Yes and No are deliberately asymmetric: an unsupported No may cause one more enquiry, while an unsupported Yes may cause a disabled person to make a journey they cannot complete.

The project has a 392-test suite covering its core rules, API routes, CLI, portable skill, failure handling, phone-number safety, and accessibility behavior. Accessibility checks run in CI alongside type checking, the application build, and checks that keep the standalone skill synchronized with the main catalogue.

I am also proud that the public contribution is useful outside this application. The skill contains the 30-need catalogue, safety guidance, examples, practice fixtures, real-call support, and the ability to resume a call without dialing again.

What we learned

I learned that structured AI output is the beginning of validation, not the end. A valid enum value can still be wrong. For decisions with real physical consequences, the application around the model must enforce its own evidence rules.

I also learned that phone calls are valuable here because accessibility is operational. A directory may say that a venue has a lift; the person answering the phone can say whether it is working today. The call reaches information that may never have been published, while the quote preserves where that information came from.

Building the real-call path changed the architecture. Phone work is asynchronous, retries have human consequences, transcripts can contain personal information, and provider failures must not be attributed to the person being called. Those concerns shaped the product more than the happy path did.

Finally, accessibility work cannot be postponed until the interface looks finished. Keyboard behavior, focus movement, plain-language errors, live updates, contrast, and no-JavaScript behavior all affected component and data-flow decisions. Treating them as requirements early made the overall product more robust.

What's next for Is it accessible?

The first priority is structured testing with disabled users, including people with mobility, vision, hearing, sensory, and cognitive access needs. The current catalogue comes from published guidance and lived experience, but real user testing should decide which questions are missing, unclear, or too burdensome.

I also want to test the full flow with NVDA, JAWS, and VoiceOver, then publish the findings and fixes. Automated accessibility checks will remain a baseline rather than a substitute for assistive-technology testing.

On the product side, I would add saved profiles, public sign-up, scheduled freshness checks for information that changes, and a consent-based way to turn individual reports into time-stamped community knowledge. Venues could confirm or update an answer, while users would still see who said what and when rather than receiving an unexplained badge.

Release "Is it accessible?" as part of Access Path, my community powered accessibility review platform.

The longer-term goal is simple: make checking a new place routine enough that disabled people can spend less energy proving whether they can enter it.

Bonus

Hindi call demo: Download Audio

Built With

Share this project:

Updates

Submission history