Mobile

Adding a mobile app API to a web platform that’s been running for years

Your data and your rules already live in the web app. How to give a mobile app access to them without rewriting the platform or breaking the web side.

The short answer

When a platform has years of business rules behind it, the safest way to add a mobile app is an API that lives inside the platform and calls the same code the web app does. You avoid two copies of the rules drifting apart. Most of the work isn’t writing endpoints; it’s finding the places where the web app assumes a browser.

Should a mobile API be a separate service?

On a university platform in Southern Africa, students wanted their grades, fees, wallet, transcripts and messages on their phones. The platform had grown for years into a large application with dozens of plugins, and each institution on it had its own settings and rules.

The rules that matter, such as who can see what, how fees are worked out and what a student is blocked from, all lived in that application. A separate API service would have had to copy them or call back into the platform for nearly everything. So we built the API as a self-contained plugin inside the platform:

  1. Its own routes and controllers under a versioned path (/api/v1), so nothing in the web app had to change.
  2. The same models and permission rules as the web app. A student signs in and gets a token, and from then on the same rules decide what they can see.
  3. A switch per institution, so the API could be turned on for one university at a time.
  4. A shared base controller for sign-in and errors, which a desktop app later reused.

Decide early how sign-in tokens expire and how they’re revoked. Students don’t want to sign in every day, so sessions on a phone tend to get longer over time. Long sessions are only safe if you can end them, for example on logout or a password change, and that’s much easier to design in than to add later.

What breaks when you add an API to a web app?

The web app had rules that ran before every page. If a student owed fees, needed to update their details or was waiting on a sponsor, they were redirected to a page explaining why. In a browser that’s helpful. In an API, a redirect to an HTML page is a response the app can’t read.

Three of these rules broke the API as they were added over the following months. The fix was the same each time: skip the redirect for API requests and expose the restriction as data. The app now calls one endpoint that returns every restriction that applies to the student, each with a message, and shows them in its own screens.

If you’re planning an API for an existing web app, list every rule that runs before a page loads, before you write the first endpoint. Each one either doesn’t apply to the API, or needs an API-shaped version.

What should every API response look like?

Every response uses the same envelope: a status, a human-readable message and the data, with an HTTP status code to match. Errors come back as one translated message rather than a list. We made that change early, once it was clear the app would otherwise have to handle both shapes.

{
  "status": "error",
  "message": "Your current password is incorrect",
  "data": null
}

By the end there were 81 endpoints, from sign-in and profile to fees, registration, requests and messages, all documented in an OpenAPI (Swagger) spec with a schema for each response. We added the documentation after the first batch of endpoints existed. Start with it instead: writing the schema first forces the conversation about field names and empty states before anyone builds against them.

How do you handle PDFs, payments and push notifications?

  1. PDFs. Transcripts and receipts were already generated as PDFs for the web. The API renders the same documents and returns a link. Copying the transcript templates into the API was quicker at first, but it means every later change to the web transcript has to be made twice, or the two drift apart. Sharing one template is worth the extra effort.
  2. Payments. The web app already handled several payment gateways. Rather than rebuild them, the API returns a link to the existing payment page, signed in with the student’s token, and the app opens it in a web view. That’s one payment flow to maintain instead of two.
  3. Push notifications. These go through a cloud push service, with one record per device, so a student signed in on a phone and a tablet gets both. Devices whose sessions have expired are cleaned up on a schedule. The first version picked every student with the app as recipients, not just the people a message was for; we caught it the next day. Test notification code with more than one user in the data, because a query that looks right with one user can be wrong with two.

One more thing to plan for: push services change. The one we used, Amazon Pinpoint, is being retired by AWS in favour of AWS End User Messaging, so apps built on it need a migration. Keeping push behind one small service class turns that into a contained change instead of a hunt through the codebase.

Frequently asked questions

Should we build a separate backend for our mobile app?

Usually not, if your web platform already holds the data and the business rules. An API inside the platform reuses them. A separate backend makes sense when the app needs data the platform doesn’t have, or when the platform can’t be changed.

How long does it take to add a mobile API to an existing platform?

It depends on how much of the platform the app needs. The student app’s API grew over about nine months, alongside other work on the platform. A first release with sign-in and a few read-only screens can ship much sooner.

Can the app reuse our existing payment setup?

Often, yes. Opening the existing, already-tested payment page inside the app avoids rebuilding gateway integrations. Check the app store rules for your case first: digital goods sold inside an app usually have to go through the store’s own payments.

Want your platform in your customers’ pockets?

Tell us what it is. Within 2 business days we'll reply with whether it needs custom software, an AI workflow or an agent, and roughly what it would take.