DEV Community

Popoola Temilorun
Popoola Temilorun

Posted on

How I Safely Added New Fields to My Django API Without Breaking Existing Users (Inboxit Case Study)

While building Inboxit a plug-and-play tool that forwards website form submissions to email, Slack, or WhatsApp, I needed to add new fields and change serializers to support more features.

The API was already live in production with real users. Changing models and serializers risked breaking existing integrations.

Here’s exactly how I handled it using the Expand-Contract pattern and API versioning.

The Situation

I had to add new fields to the main model. At the same time, I wanted to improve the response structure.

If I just updated the existing serializer, all current integrations would break.

My Approach: API Versioning + Expand-Contract

I decided to introduce v2 while keeping v1 fully functional.

Step 1: Expand

  • Added the new fields to the Django model (kept the old fields intact).

Here’s what the model looked like after adding the new fields:

Model with additional fields

Step 2: Versioning in URLs

I set up URL versioning so both versions could coexist:

# urls.py
urlpatterns = [
    path('api/v1/', include('inboxit.api.v1.urls')),   # Old version (still active)
    path('api/v2/', include('inboxit.api.v2.urls')),   # New version
]
Enter fullscreen mode Exit fullscreen mode

Old clients continue using /api/v1/ without any change.

Step 3: Migration & Contract Phase

  • Updated code to support both versions where needed.
  • Added logging to track which version clients were using.
  • Once most traffic moved to v2, I’ll fully deprecate v1 with proper notice.

Key Lessons

  • Never modify a live API in place if users depend on it.
  • Use versioning early (/api/v1/, /api/v2/) to give yourself room to evolve without affecting integrations.
  • The Expand-Contract pattern (add new → migrate → remove old) prevents painful rollbacks.
  • Always communicate deprecation timelines to users.

This approach let me add new features to Inboxit without disrupting existing integrations.

Have you had to version an API in production?

What strategy worked best for you — URL versioning, header-based, or something else?

I’d love to hear your experiences in the comments 😎😎.

Top comments (0)