A web frontend is redeployed with the backend. A mobile app isn't: people keep old versions installed for months, on networks that drop out mid-request. That changes how I design Django APIs.

Version from day one

Put a version in the URL (/api/v1/) before the first release. When a breaking change comes, and it will, the old app keeps working against v1 while the new one moves to v2.

Paginate everything that's a list

Never return an unbounded list. Cursor pagination works well for feeds because new items don't shift pages around:

REST_FRAMEWORK = {
    "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.CursorPagination",
    "PAGE_SIZE": 20,
}

Return what the screen needs

If a screen shows a list of bookings with the customer's name, include the name in the booking payload. Making the app fetch each customer separately turns one request into twenty on a slow connection.

Consistent errors

Pick one error shape and use it everywhere, so the app can show a sensible message without special cases:

{ "error": "validation_error", "fields": { "email": ["Enter a valid email."] } }

Tokens that refresh

Short-lived access tokens with a refresh token keep users signed in without long-lived secrets on the device. Make sure the app handles a 401 by refreshing once and retrying, not by logging the user out.

Make writes safe to retry

When a request times out, the app doesn't know whether it succeeded. Accept a client-generated idempotency key on important writes such as payments and bookings, so a retry doesn't create a duplicate.

None of this is complicated, but adding it later, after thousands of installs, is much harder than starting with it.