REST API Design for Mobile Sales Apps

  • REST API
  • Backend
  • Mobile

REST API design rules for mobile and sales-force apps: versioning, idempotent writes, pagination, incremental sync and consistent error formats.

An API for a mobile sales app has harder conditions than one for a website. Clients run old versions for months, networks drop mid-request and one bad response can stop a salesperson working. These are the rules I apply when designing sales-force APIs.

1. Version the API and keep old versions alive

Put the version in the path, such as /api/v1/orders. Adding a field is safe. Removing or renaming one is a breaking change and needs /v2. Keep the old version running until usage data shows the old app builds are gone.

2. Make writes idempotent

On a weak connection the app may send an order, lose the response and send it again. The server must recognize the repeat. Have the client generate a unique key per action and send it in a header. Store the key with the result and return the same result for a repeated key.

POST /api/v1/orders
Idempotency-Key: 0b9d6c1e-4a7f-4f0e-9d53-2f1f6a7c9e11

201 Created   (first time)
200 OK        (same key again, same order returned)

3. Use HTTP status codes honestly

  • 200 and 201 for success, 204 when there is nothing to return.
  • 401 when the token is missing or expired, 403 when the user is not allowed.
  • 404 for a missing record, 409 for a conflict with current state.
  • 422 for validation errors, with a message per field.
  • 5xx only for real server faults, never for a business rule.

4. One error format everywhere

The app should parse errors with one piece of code. Pick a shape and never deviate.

{
  "message": "The order could not be saved.",
  "errors": {
    "lines.0.quantity": ["Quantity must be at least 1."]
  }
}

5. Paginate and filter lists

Never return an unbounded list. For data that changes while the user scrolls, cursor pagination is more stable than page numbers, because new rows do not shift the pages.

6. Support incremental sync

A device should not download the whole customer list every morning. Accept an updated_since parameter and return only changed records, including a marker for deleted ones. This is essential for offline-first apps.

7. Send only what the screen needs

Mobile data is slow and sometimes expensive. Return compact resources, enable gzip compression and avoid making the app call five endpoints to draw one screen.

8. Secure by default

  • HTTPS only, with short-lived or revocable tokens per device.
  • Check authorization on every record: a sales officer sees only their own customers.
  • Rate-limit login and write endpoints.
  • Record who did what, from which device and app version.

For a concrete implementation with Laravel and Flutter, see connecting a Flutter app to a Laravel API.

Common questions

What makes an API idempotent?

An idempotent API gives the same result when the same request is sent more than once. For POST requests this is usually done with a client-generated idempotency key that the server stores with the result.

How should a mobile API be versioned?

Put the version in the URL path, for example /api/v1. Make only additive changes within a version and introduce a new version for breaking changes, keeping old versions alive while old app builds are in use.

Which HTTP status code should validation errors use?

Use 422 Unprocessable Entity with a JSON body that lists the error messages for each field.