Model or dataset
microsoft/call-center-ai avatar
microsoft/call-center-ai

microsoft/call-center-ai: an API that places phone calls and fills a claim schema

Send a phone call from AI agent, in an API call. Or, directly call the bot from the configured phone number!

6,568 stars783 forksPythonApache-2.0

At a glance

What is it?
This is an Azure-hosted Python service that turns an HTTP POST into an outbound AI phone call and returns a structured record of what was said. It is aimed at teams already inside Azure who need low to medium complexity calls handled, not at anyone wanting a self-contained voice stack.
Who is it for?
Adopt it if you are already on Azure, your calls are scripted around a claim schema, and you accept that the bot is bound to Azure Communication Services, Cognitive Services and OpenAI resources. Do not adopt it if you need a carrier-neutral or self-hosted voice stack, or if your calls are open-ended rather than form-filling.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 76 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem: turning a phone call into a filled-in form

Most voice bot projects stop at conversation. This one starts from the record it wants to produce. The README frames the use case as insurance, IT support and customer service, and the request body makes the intent explicit: you send a claim array where each entry has a name and a type, and the agent's job during the call is to gather those fields. In the worked example the fields are hardware_info, first_seen and building_location. The demo output shows the same idea with an insurance claim: incident_description, incident_location, involved_parties and policy_number, all populated from a French-language call. The audience is therefore narrow and specific. It is for a team that already receives calls or wants to place them, has a defined set of questions, and wants the answers in a database row rather than a transcript someone has to read. If your calls are exploratory, or your output is a decision rather than a set of fields, the claim schema is working against you rather than for you.

What the POST /call request actually carries

The README gives one curl example and it is the clearest statement of the interface. You POST JSON to a /call endpoint with bot_company, bot_name, phone_number, task and agent_phone_number, plus the claim array. bot_company and bot_name set the persona; in the example the assistant is Amélie working for Contoso. task is free text describing the objective, and the README's own wording is instructing: the assistant works for the IT support department, helps with the issue, and gathers information in the claim. agent_phone_number is a separate number, which suggests a human fallback path, consistent with the feature list mentioning human agent fallback. Nothing in the supplied material documents authentication on that endpoint, rate limits, or what the response body contains. That is a gap worth noting rather than guessing about. The endpoint is the whole product surface: everything else in the repository exists to make that one request produce a phone call and a stored record.

The data flow: telephony in, structured JSON out

The pipeline visible in the material runs through Azure. Azure Communication Services carries the call, Cognitive Services handles speech, and OpenAI resources supply the model. The README states that conversations are streamed in real time to avoid delays, can be resumed after disconnections, and are stored for future reference. Streaming matters here because a turn-based pipeline that waits for a full recording before transcribing would add seconds to every reply. Resumption matters because phone calls drop. The stored record has a consistent shape across both the feature description and the demo extract: messages with created_at, action, content, persona and tool_calls; a claim object; a next object with an action and a justification; a reminders array with title, description, owner and due_date_time; and a synthesis with long, short, satisfaction and improvement_suggestions. The next.action value in the demo is case_closed, which implies a small set of terminal states the model chooses from. Redis is named for caching, and Application Insights for monitoring and tracing. The README also mentions retrieval-augmented generation over internal documents and fine-tuning on historical conversations, though it does not show configuration for either.

Deployment is Azure-shaped, and that is the main constraint

The README describes a containerized, serverless architecture on Azure, with provisioning of LLM resources called out as a way to reduce latency. There is a GitHub Codespaces badge pointing at a quickstart, so the fastest path to a running instance is a Codespace rather than a local install. What the supplied material does not give is the deployment command itself. There is no terraform apply, no az deployment, no Bicep file name, no list of environment variables. If you are evaluating this for adoption, the first thing to check in the repository is how the infrastructure is declared and which resource types it creates. The provider lock-in is not incidental. Swapping Azure Communication Services for another telephony provider would mean replacing the call handling layer, and the model choice is expressed in OpenAI resource terms. The README's own note that gpt-4.1 and gpt-4.1-nano carry a 10 to 15x cost premium over the cheaper tier is a useful signal: model selection is a cost lever you will be adjusting, and the nano variant exists for that reason.

Where the design strains: latency, cost and the schema itself

Three limitations follow from the material. First, latency. Streaming reduces delay but does not remove it, and the README explicitly suggests provisioning LLM resources to cut it, which means the default deployment is not the fastest configuration. Second, cost. A live phone call holds a model in a loop for its full duration, and the README itself flags the premium tier. Call length is the cost driver, and a bot that handles long, meandering calls will cost more than one that closes them. Third, the schema. A fixed claim array is a good fit for insurance intake and a poor fit for anything where the important information is not known in advance. There is also a quality question the README raises without answering: the synthesis object includes improvement_suggestions and a satisfaction field, which implies the system is scoring its own calls, but nothing in the supplied material says how that score is computed or whether it is reliable. Treat it as a signal to review, not a metric to trust.

The honest alternative: a speech pipeline you assemble yourself

The obvious comparison is a general voice agent framework built on a real-time speech API, where you write the turn loop and choose the telephony provider separately. The difference is where the structure lives. Here, the claim schema, the reminders, the next-action decision and the synthesis are part of the product, and the model is prompted to fill them. In a hand-assembled pipeline you would build each of those as your own tool call or post-processing step, which gives you control over the prompt, the model and the carrier, at the cost of writing and maintaining the orchestration. If your calls genuinely fit the claim pattern and you are on Azure, the assembled version is duplicated work. If your calls do not fit the pattern, you are fighting the abstraction. There is no middle ground offered in the material: the interface is a task string plus a field list.

Licence and the cost of keeping up

The repository is Apache-2.0, which permits commercial use and modification and includes an explicit patent grant. It does not cover the Azure services the code calls, and it does not cover the model weights or the OpenAI API terms, which are separate agreements you accept when you deploy. The release cadence visible in the supplied data is rapid: v17.4.0, v17.4.1 and v17.4.2 all landed within four days in May 2025, and the last push to the default branch is dated 2026-07-01. A patch-level burst like that usually means fixes shipping quickly, which is good for users and also means you should pin a version rather than track main. Upgrading carries two kinds of cost: the code itself, and the prompts and model versions bundled with it, since a change in how the claim is extracted can alter your stored data shape. Budget for reading the diff on every minor bump, not just the major ones.

Editorial conclusion

Adopt it if you are already on Azure, your calls are scripted around a claim schema, and you accept that the bot is bound to Azure Communication Services, Cognitive Services and OpenAI resources. Do not adopt it if you need a carrier-neutral or self-hosted voice stack, or if your calls are open-ended rather than form-filling. Before committing, verify the Terraform or Bicep deployment in the repository, the current gpt-4.1 pricing against your call volume, and whether the call recording and Application Insights telemetry you enable match your own data-retention rules.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. microsoft/call-center-ai on GitHub
  4. README
  5. Releases
Community notes

Community notes