Windows-Copilot-API: an OpenAI-compatible shim over the consumer Copilot web chat
Reverse engineered Windows Copilot into an OpenAI-compatible API. Access GPT-4 and GPT-5 models through a simple REST interface without API keys or billing.
At a glance
- What is it?
- This project wraps a signed-in copilot.microsoft.com browser session behind a local OpenAI-format API and a Python client. It removes API keys and billing from the loop, but it inherits the browser session's lifetime and Cloudflare clearance as hard constraints.
- Who is it for?
- Adopt this if you want a local, OpenAI-shaped endpoint backed by a Copilot account you already have, and you accept that the session lives in session/ and needs a visible browser to refresh clearance. Do not adopt it for unattended services, CI pipelines or anything that must survive a 30-minute clearance expiry without a human at the host.
- Can I use it commercially?
- Yes. MIT 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 80 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 gap this fills: a REST endpoint for an account, not for a key
Most OpenAI-compatible servers assume you hold an API key with a provider that bills per token. This project inverts that. The README describes it as using your own Microsoft Copilot account, with no API key, no credits and no paid plan, turning the free chat at copilot.microsoft.com into something callable from code. The credential is a browser session, not a secret string. That single design decision explains nearly every other property of the project: why setup opens a real browser, why the session directory is git-ignored, why the Docker path needs a host-side login, and why the failure mode is a 503 rather than a 401. The audience is narrow and specific. It suits a developer who already signs into Copilot in a browser, wants to script prompts against that same account, and does not want to introduce a billing relationship. It is a personal-use automation tool, and the README says so directly, noting the project is unofficial and not affiliated with or endorsed by Microsoft.
Two entry points over one session: CopilotClient and app.py
There is no single interface. The README offers two, and they share the same underlying signed-in session rather than two separate auth paths. The first is a Python library. CopilotClient() loads the stored session, chat() returns a reply object with .text and a conversation_id, and passing that id back continues the same thread. stream() yields the answer piece by piece. The second is a server. Running python app.py starts what the README calls a Copilot OpenAI-compatible API on http://127.0.0.1:8000, exposing POST /v1/chat/completions with support for "stream": true. The model name in requests is "copilot", and the API key field is required by the OpenAI SDK but ignored by the server. That is the whole architecture as documented: a session on disk, a client that uses it, and an HTTP layer that translates OpenAI-shaped requests into the same calls. There is no queue, no cache and no scheduler described, which matters for the concurrency discussion below.
Setup is three commands plus a browser window you must watch
Installation is Python 3.9+, a virtual environment, then pip install -r requirements.txt, playwright install chromium, and python -m copilot login. The login step is not a token paste. A browser opens, you sign in with a Microsoft or Google account, and the README states the browser closes by itself once sign-in is detected. After sign-in the project sends one short warm-up message that the README says mints the chat token and passes Cloudflare's human check in the same step, leaving a small throwaway chat in your history. If a checkbox appears, you click it in that window. Steps are logged to session/login.log. The session is saved under session/, which the README says is git-ignored and never shared. Two consequences follow. First, the first request works immediately because the warm-up already earned clearance. Second, the credential is a file on disk tied to a browser profile, so the security question is filesystem access to session/, not key rotation. If you are evaluating this for a shared machine, that is the thing to think about before anything else.
Docker works, but only as a consumer of a session earned elsewhere
The Docker path is the clearest illustration of the project's boundary. docker compose up --build maps port 8000 and bind-mounts session/ so the login persists across restarts. The README is explicit that you must sign in on the host first, because the login step opens a visible browser and that cannot run inside the headless container. The container reuses the Cloudflare clearance earned on the host and refreshes the chat token headlessly. What it cannot do is earn fresh clearance without a visible browser. The README states that when clearance expires, roughly every 30 minutes, the container returns a 503, and the remedy is to re-run python -m copilot login on the host to refresh session/. For a manual build, the equivalent is docker run --rm -p 8000:8000 -v "$(pwd)/session:/app/session" windows-copilot-api. This is a genuinely useful deployment shape for a workstation or a home server you can reach, and a poor fit for anything you expect to stay up unattended. The 503 is not a bug to be worked around; it is the design showing through.
Rate limiting is configured, not discovered
The README lists RATE_LIMIT_RPM and RATE_LIMIT_BURST as tunables in docker-compose.yml, and mentions a bundled concurrency and stress test section in the table of contents. Two things are worth separating here. The project's own limiter controls how fast your code hits the local server. It does not control how the upstream consumer Copilot endpoint responds to sustained traffic, and the README does not claim otherwise. That asymmetry is the practical risk for anyone planning to fan out requests: a local limiter can make your client well-behaved while the upstream session still degrades or the clearance still expires. If you set RATE_LIMIT_RPM, treat it as a courtesy throttle toward the upstream account rather than a guarantee of throughput. The README does not publish latency or throughput figures, and I am not going to invent any. The honest position is that the concurrency ceiling is undocumented and would need to be measured against your own account.
Where the OpenAI compatibility stops
The compatibility claim is real but bounded. The README shows the openai SDK pointed at base_url="http://localhost:8000/v1" with api_key="unused", and a plain curl call to /v1/chat/completions. Model selection is not meaningful in the OpenAI sense: the model string is "copilot", which routes to whatever Copilot serves for that account. The README's own description mentions GPT-4 and GPT-5 models, but there is no documented way to pin a specific model per request, and no model list endpoint appears in the endpoint table. So applications that switch models by name, or that rely on token accounting fields, will find the shim thinner than they expect. Multi-turn state is handled through conversation_id in the Python client, which is a project-specific concept rather than the standard messages array carrying full history. If your code already replays the whole message list each turn, that works too, but the two mechanisms are not the same thing and the README does not describe how they interact.
The realistic alternative, and the actual difference
The obvious alternative is to use a hosted OpenAI-compatible provider and pay for tokens, or to run a local model server such as Ollama or vLLM behind the same OpenAI-shaped interface. The difference is not quality, it is where the credential and the capacity live. A paid provider gives you a key that can be rotated, a documented rate limit, and an endpoint that does not expire because a browser session aged out. A local model server gives you no external dependency at all, at the cost of your own GPU and a different model. This project sits between them: it gives you no billing and no local hardware requirement, but it borrows a consumer web session that Microsoft controls and that the README itself says can lapse in about half an hour. If your workload is interactive and you are at the machine, that trade is fine. If your workload is a nightly batch job, the hosted or local options avoid a class of failure this project cannot remove. The README's own framing supports that reading: it describes automating the consumer Copilot web experience for personal use.
Maintenance cost and what the MIT licence does not cover
The repository is MIT licensed, which governs the code you clone. It does not govern the service the code talks to. The README states plainly that the project is unofficial, not affiliated with or endorsed by Microsoft, and asks that you use it responsibly and within Microsoft's terms. That distinction is the one to hold onto: an MIT grant on the client does not grant any right to the upstream endpoint, and the terms of the consumer Copilot product are a separate matter that I am not in a position to interpret. On maintenance, the last push recorded is 2026-06-27 and no releases are listed, so there is no versioned artifact to pin. You would be tracking the master branch. The practical cost driver is not code churn but the browser automation surface: Playwright, a Chromium install, a login flow and a Cloudflare clearance step are all things that can break independently of this repository's own commits. Budget for re-running python -m copilot login whenever requests start returning 503, and check session/login.log when the login itself misbehaves.
Editorial conclusion
Adopt this if you want a local, OpenAI-shaped endpoint backed by a Copilot account you already have, and you accept that the session lives in session/ and needs a visible browser to refresh clearance. Do not adopt it for unattended services, CI pipelines or anything that must survive a 30-minute clearance expiry without a human at the host. Before committing, verify three things yourself: that python -m copilot login completes and writes a usable session/, that /v1/chat/completions returns a normal completion through the openai SDK with model="copilot", and that your intended runtime is not the headless container described in the Docker section.
Community notes