Mobile Apps
One OpenAPI contract, and every client built against it — iOS, Android and web. Because the hard part of a mobile product was never the screens.
API-first means the contract between app and server is written before either is built. Onpolar defines one OpenAPI specification, generates typed clients from it, and builds the mobile app and the backend against that single document — so iOS, Android, web and any AI consumer cannot drift apart as the product changes.
The problem
Screens are tractable. What sinks mobile products is everything behind them: an API that changed shape without telling the app, offline state that lies, a push token nobody refreshed, and three clients that each implemented the same business rule slightly differently.
It compounds on the second platform. Every endpoint wired up by hand is an endpoint that can drift, and a bug that reproduces on Android but not iOS is usually a bug in the contract rather than in either app.
So we write the contract first and generate the clients from it. The app, the web frontend and any AI consumer all read one document, and a breaking change gets caught by the compiler instead of by a reviewer.
What you get
The specification is the source of truth. Typed clients are generated from it, so a server change that breaks the app fails the build rather than the release.
Go and PostgreSQL, with the auth, roles and data model the app depends on — not a mobile shell over an API you are still hoping somebody builds.
Cross-platform where the product is screens over data, with native modules dropped in where a platform capability genuinely needs them.
Token lifecycle handled, delivery observable, and a permission prompt that arrives at a moment the user understands why.
Biometric unlock, tokens in the platform keystore, and a refresh flow that does not sign people out on a flaky train connection.
A local cache with an explicit conflict policy, so the app is honest about what it holds and what it has not managed to send yet.
Build pipelines, signing, staged rollout, and the review round trips handled by someone who has had them before.
Symbolicated crashes, release-over-release comparison, and enough product analytics to know which screens earn their place.
How it works
Endpoints, payloads, error shapes and auth agreed as an OpenAPI document. Every client is generated from it, which makes this the cheapest possible place to change your mind.
The Go service, the data model, and typed clients built from the spec. The app has something real to talk to before the first screen exists.
Screens, navigation, offline behaviour, push and auth — against a contract that has already stopped moving.
Signing, staged rollout, crash reporting wired, and the first review rejection absorbed without it becoming a crisis.
Bring the use case. We will tell you whether it needs a store listing, a web app, or just an API — including when that answer costs us the project.
Approach fit
This decision usually gets made on preference and defended afterwards. It should be made on what the product actually has to do.
| Approach | Choose it when | The cost you accept |
|---|---|---|
| Cross-platform | The product is screens over data, and both platforms should behave the same | Platform-specific polish takes more effort; some native APIs need a bridge |
| Fully native | Camera, sensors, background processing or frame-rate is the product | Two codebases, two release cycles, roughly two of everything |
| Progressive web app | No store distribution needed, and reach matters more than device integration | Weaker push and background support on iOS; no store presence at all |
| Web app in a wrapper | An existing web product needs a store listing more than it needs native behaviour | Review teams reject thin wrappers, and it feels like a website — because it is one |
The contract-first backend is identical in all four cases, which is rather the point: the client decision stops being irreversible.
FAQ
Our published case studies are web platforms and SaaS, so the honest answer is that our mobile evidence is the API layer rather than a store listing we can point you at. ERPFlow was built API-first on one OpenAPI contract precisely so web, mobile and AI clients could be served from it. If a downloadable app in our portfolio is your bar for this work, say so early and we will tell you plainly whether we are the right shop.
Cross-platform, unless the product is genuinely about sensors, camera, background processing or frame-rate. Most business apps are screens over data, and maintaining two codebases for that is a cost with no return. The matrix above is the one we actually use.
Yes, and the first thing we do is write the contract for what exists. If there is no specification, we produce one from the running API and confirm it against real responses — because a client generated from a guess is a client that breaks silently.
Often not. With no push, no offline use and no device capability in play, a fast web app reaches more people for less money and ships without a review queue. We would rather talk you out of an app than build one nobody installs.
You do, in your name, from the start. App Store and Play listings, signing certificates and the repository are yours. Apps held hostage inside an agency account are a well-documented way to lose control of a product.
Days, usually, plus whatever the first rejection costs. First submissions get rejected on metadata, privacy declarations and account-deletion requirements far more often than on code, so we prepare those before submitting rather than after.
Fixed-scope phases against the spec, as with our other builds. The contract phase is priced separately and deliberately — it is worth doing even if you stop there, because the specification is yours to take elsewhere.
They belong behind the same contract as everything else, scoped to what the signed-in user may see, with model routing through a gateway. An assistant in a mobile app that ignores permissions is a data-leak feature with a nice animation.
Tell us what the app has to do and what already exists. We reply within one business day.