# Your Desktop App Is Your Best API Auditor
Most web applications ship APIs that look complete on paper but have never been tested by a real client. The web app — the only consumer — bypasses the API entirely, rendering data server-side with template logic. The API exists, the docs page works, but nobody has actually built anything against it.
## The Web App Can Cheat
Django (or Rails, or any server-rendered framework) can cheat. Need a list of projects with their task counts? Throw a queryset annotation into the view, pass it to a template tag, done. The data never touches the API.
This means:
- Endpoints that return incomplete data go unnoticed
- Missing filters, search, and custom actions aren't felt
- Inconsistent URL patterns don't matter when the server handles routing
- Data shapes that would be awkward for a client are invisible
## A Native Client Can't Cheat
When you build a desktop or mobile app against your own API, every shortcut is exposed:
- **Missing endpoints**: The Flutter app tried to load events and hit a 404 — the ViewSet existed but wasn't registered in the main router. The web app worked fine because it never used that route.
- **Fragmented paths**: Notes at `/api/notes/`, messages at `/messages/api/threads/`. Three separate routers for one API. A web app doesn't care. A mobile developer stares at this for an hour wondering what they're doing wrong.
- **Missing actions**: Need to filter tasks by project AND status? The web app just chains `.filter()` in the view. The API might not expose those query parameters at all.
- **Incomplete responses**: The web template can call `file.derived_files.count` in a loop. The API serializer might not include that field, because nobody asked for it.
## The Hidden Cost to Outside Developers
This is where it really hurts. You ship your API, someone gets hired to build an integration, and they hit wall after wall:
- Endpoints at inconsistent paths
- Filters that work on some resources but not others
- Data shaped differently between similar endpoints
- Custom actions that aren't documented because the web app never needed them
And they blame themselves. "I must be doing something wrong." They spend days debugging what's actually a gap in your API. They might not even realize the problem is on your side — they just think your API is hard to work with and move on.
You'd never hear about it.
## The Native App as First External Developer
Building a desktop or mobile client against your own API is the cheapest way to find these problems before a customer does. Every pain point the native app hits is a pain point an integration partner would hit.
In practice, building the AskRobots Flutter app exposed:
- An events endpoint that was registered at the wrong path
- API path fragmentation across three separate routers
- Missing REST endpoints for features that only had MCP access
- Dashboard data that had no API at all — the web page aggregated it server-side
- The realization that 5 features could be added immediately (API ready) while 5 others needed backend work first
None of this was visible from the web app. Everything worked. The API just hadn't been pressure-tested.
## The Virtuous Cycle
Each client you add tightens the whole system:
1. **Flutter app** tries to build a screen → finds API gap
2. **Fix the API** for Flutter → MCP server gets better (same endpoints)
3. **Better MCP** → AI agents work more reliably
4. **AI agents** hit the API harder → find more edge cases
5. **Outside developers** eventually connect → everything just works
The first native client is the most valuable one. Not because of the app itself, but because of everything it forces you to fix underneath.