In this article · 13 sections
A mobile app is only as good as the API behind it. Unlike a website that you can update instantly, an app on someone’s phone may be months out of date, running over a slow connection and expecting your server to behave exactly as it did when that version shipped. These conditions make API design a first-class concern.
This guide covers practical principles for building APIs that mobile apps can depend on. For the wider architecture decision, see choosing a backend for your app.
Design for the client’s needs
Start from the screens, not the database. List what each screen needs and design endpoints that deliver it efficiently.
- Avoid forcing the app to make many sequential calls to render a single screen
- Avoid returning huge objects full of fields the app never uses
- Consider endpoints shaped around app needs, or a flexible query layer such as GraphQL, if over-fetching and under-fetching are persistent problems
Use consistent REST conventions
For REST-style APIs, consistency makes everything easier to learn and debug.
- Use nouns for resources and HTTP methods for actions:
GET /orders,POST /orders,GET /orders/123 - Use the correct methods: GET reads, POST creates, PUT or PATCH updates, DELETE removes
- Choose standard status codes: 200 and 201 for success, 400 for bad requests, 401 for unauthenticated, 403 for forbidden, 404 for not found, 409 for conflicts, 429 for rate limiting, 500 for server errors
- Keep naming style consistent across endpoints and fields
- Return JSON with predictable structure and types
Version your API
Old app versions stay in the wild. If you change the API in a breaking way, those users could crash.
- Include a version in the URL (
/v1/…) or a header - Add, don’t change: introducing new optional fields is safe, while removing or renaming fields is not
- Support older versions for a defined period and communicate deprecations
- Provide a minimum supported version mechanism so you can prompt very old clients to update
Handle errors clearly
A useful error response helps the app and the developer.
{
"error": {
"code": "invalid_email",
"message": "Please enter a valid email address.",
"field": "email"
}
}
- Use stable machine-readable codes the app can act on, and human-readable messages for display or logs
- Never expose internal stack traces or sensitive details
- Be consistent across all endpoints
- Make it possible to correlate an error with server logs, for example with a request ID
Paginate lists
Never return unbounded lists. Mobile devices and networks cannot handle them.
- Cursor-based pagination is usually more reliable than page numbers for feeds that change while the user scrolls
- Return the next cursor and whether more results exist
- Allow reasonable page-size limits
- Support filtering and sorting where users need them
Keep payloads small
- Return only the fields needed, or allow clients to request specific fields
- Use compression (gzip or Brotli)
- Serve appropriately sized images through a CDN, with multiple sizes available
- Avoid sending large JSON when a smaller response will do
Smaller responses mean faster screens, lower data use and better battery life. See app performance optimisation.
Design for unreliable networks
Mobile connections drop, switch and slow down.
- Make write operations idempotent where possible, using idempotency keys for payments and orders so retries do not create duplicates
- Support conditional requests and caching with
ETagandCache-Control - Use sensible timeouts and let the app retry with backoff
- Consider offline-first designs where the app queues changes and syncs later. See offline-first mobile apps.
Secure the API
Security cannot rely on the app alone, since anyone can inspect traffic and call your API directly.
- Use HTTPS only
- Authenticate with standard protocols such as OAuth 2.0, using short-lived access tokens and refresh tokens
- Authorise every request on the server, checking that the user may access that specific resource
- Validate input strictly and guard against injection
- Apply rate limiting and abuse detection
- Never rely on hidden endpoints or secret URLs
- Return the minimum data necessary
The mobile app security checklist covers these in more depth.
Document and test
- Describe the API with a specification such as OpenAPI, and generate documentation and client code
- Provide a sandbox or staging environment
- Write contract tests so changes that break clients are caught before release
- Monitor latency, error rates and usage by endpoint and by app version
Support real-time features carefully
For chat, live scores or collaboration, consider WebSockets, server-sent events or managed real-time services. Plan for reconnection, message ordering and battery use, and fall back gracefully when the connection fails.
Common mistakes
- Designing endpoints around database tables instead of app needs
- Breaking changes without versioning
- Unbounded list responses
- Inconsistent error formats
- Trusting the client for authorisation
- Ignoring slow or interrupted connections
Checklist
- Endpoints designed around real screens
- Consistent REST conventions and status codes
- Versioning and a deprecation policy
- Standard error format with codes and request IDs
- Cursor pagination and size limits
- Compression, caching and small payloads
- Idempotent writes and retry-friendly design
- HTTPS, token auth and server-side authorisation
- OpenAPI documentation and contract tests
- Monitoring by endpoint and app version
Final thoughts
Great APIs are predictable, forgiving and secure. Design for the client you will have in six months, not just the one you ship today. For help designing and building reliable backends, see our app development service or contact us.