Chaturmind
LearnDSASystem DesignDevOpsEngineering GrowthBlog
Start learning
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML
  • DevOps
  • Engineering Growth

Company

  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← System Design Interview Playbook

Interview Framework

  • The 6-Step Design Framework
  • HLD Fundamentals Refresher
  • Requirement Gathering Practice
  • Domain Decomposition
  • API Contract Design
  • Data Ownership Model
  • Failure Scenario Walkthroughs
  • Architecture Diagramming
  • Back-of-Envelope Estimation

10 Case Studies

  • Design a URL Shortener
  • Design Twitter / X
  • Design WhatsApp
  • Design Netflix
  • Design a Rate Limiter
  • Design a Search Autocomplete
  • Design a Distributed Cache
  • Design a Notification Service
  • Design Uber / Ride Sharing
  • Design a Distributed File Storage System
  • Design a Distributed Task Scheduler
  • Design a Message Queue System
  • Design an Authentication System at Scale
  • Design a Distributed Logging & Metrics Pipeline
  • Design a Food Delivery Platform
  • Design a Real-Time Analytics Dashboard
  • Design a Monitoring & Alerting System
  • Design Container Orchestration Basics
  • Design a CI/CD Pipeline System
  • Design Service Mesh Basics
  • Design a Centralized Configuration & Secrets System
  • Design a Batch Processing System
  • Design a Data Warehouse / Analytics Storage Layer
  • Design Global Content Delivery
  • Case studies

    🏗️Design a URL Shortener
  • 🏗️Design a Rate Limiter
  • 🏗️Design Twitter / X
  • 🏗️Design WhatsApp
  • 🏗️Design Netflix
  • 🏗️Design a Distributed Cache
  • 🏗️Design a Notification Service
  • 🏗️Design a Search Autocomplete System
  • 🏗️Design Uber / Ride Sharing
  • 🏗️Design a Web Crawler
  • 🏗️Design a Payment System
  • 🏗️Design a Distributed Lock Service
  • 🏗️Design a Video Streaming Platform
  • 🏗️Design a Search Engine
  • 🏗️Design E-Commerce Checkout & Inventory at Scale
Chaturmind
← System Design Interview Playbook

Interview Framework

  • The 6-Step Design Framework
  • HLD Fundamentals Refresher
  • Requirement Gathering Practice
  • Domain Decomposition
  • API Contract Design
  • Data Ownership Model
  • Failure Scenario Walkthroughs
  • Architecture Diagramming
  • Back-of-Envelope Estimation

10 Case Studies

  • Design a URL Shortener
  • Design Twitter / X
  • Design WhatsApp
  • Design Netflix
  • Design a Rate Limiter
  • Design a Search Autocomplete
  • Design a Distributed Cache
  • Design a Notification Service
  • Design Uber / Ride Sharing
  • Design a Distributed File Storage System
  • Design a Distributed Task Scheduler
  • Design a Message Queue System
  • Design an Authentication System at Scale
  • Design a Distributed Logging & Metrics Pipeline
  • Design a Food Delivery Platform
  • Design a Real-Time Analytics Dashboard
  • Design a Monitoring & Alerting System
  • Design Container Orchestration Basics
  • Design a CI/CD Pipeline System
  • Design Service Mesh Basics
  • Design a Centralized Configuration & Secrets System
  • Design a Batch Processing System
  • Design a Data Warehouse / Analytics Storage Layer
  • Design Global Content Delivery
  • Case studies

    🏗️Design a URL Shortener
  • 🏗️Design a Rate Limiter
  • 🏗️Design Twitter / X
  • 🏗️Design WhatsApp
  • 🏗️Design Netflix
  • 🏗️Design a Distributed Cache
  • 🏗️Design a Notification Service
  • 🏗️Design a Search Autocomplete System
  • 🏗️Design Uber / Ride Sharing
  • 🏗️Design a Web Crawler
  • 🏗️Design a Payment System
  • 🏗️Design a Distributed Lock Service
  • 🏗️Design a Video Streaming Platform
  • 🏗️Design a Search Engine
  • 🏗️Design E-Commerce Checkout & Inventory at Scale
HomeLearnSystem DesignSystem Design Interview PlaybookInterview Framework
✓ FreeIntermediate· 8 min read

API Contract Design

Designing the API surface between services deliberately — REST vs gRPC vs async, versioning strategy, idempotency keys, and pagination — as a first-class HLD interview deep-dive, not an afterthought.

Published September 23, 2026


API Contract Design

After deciding where the service boundaries are (Domain Decomposition), an HLD interview often expects you to go one level deeper on at least one boundary: what does the actual API contract between two services look like? This is a common deep-dive target precisely because it's where vague hand-waving ("they talk over REST") gets exposed.

REST vs gRPC vs async messaging — picking deliberately

REST (JSON over HTTP):      human-readable, widely tooled, higher per-call overhead,
                             best for public/external APIs and browser clients
gRPC (protobuf over HTTP/2): binary, strongly-typed contracts, lower latency/overhead,
                             best for internal service-to-service calls at scale
Async messaging (a queue):  fully decoupled, sender doesn't wait for a response,
                             best when the caller doesn't need an immediate result
                             (see Message Queue System / event-driven patterns)

The interview-relevant answer isn't picking one universally — it's matching the choice to the actual call: a public-facing API serving browser clients reasonably defaults to REST/JSON for tooling and readability; high-volume internal service-to-service calls where latency matters benefit from gRPC's lower overhead and strict schema; anything where the caller shouldn't block waiting for the result belongs on a queue, not a synchronous call at all.

Versioning strategy

URL versioning:     /api/v1/orders, /api/v2/orders   — explicit, simple, most common
Header versioning:  Accept: application/vnd.api.v2+json  — cleaner URLs, less visible

Any API contract that will be called by more than one consumer needs an explicit versioning strategy from day one — not because v2 is needed immediately, but because retrofitting versioning onto an API with existing callers (who can't all upgrade simultaneously) is far harder than designing for it upfront. URL versioning is the most common, most interview-safe default: simple, visible, easy for callers to reason about.

Idempotency keys

POST /api/v1/payments
Idempotency-Key: client-generated-uuid-abc123

— if this exact request (same Idempotency-Key) is received again (e.g. due to a client
retry after a timeout), the server returns the ORIGINAL response instead of processing
the payment a second time

Any API that isn't naturally idempotent (a POST creating something, especially anything involving money — see Payment — Idempotency Implementation) needs an explicit idempotency mechanism, because network failures mean the client genuinely cannot always tell whether a request succeeded or just failed to return a response — a client-generated idempotency key, checked server-side before processing, is the standard answer, letting safe retries happen without risking a duplicate charge or duplicate order.

Pagination

Offset-based:  GET /orders?offset=100&limit=20
  — simple, but breaks under concurrent writes (items shift between pages)

Cursor-based:  GET /orders?after=order_id_xyz&limit=20
  — stable under concurrent writes, standard for any large or actively-changing dataset

Offset-based pagination is simple to reason about but has a real correctness problem at scale: if items are inserted or deleted while a client is paging through results, offset-based pages can skip or duplicate items. Cursor-based pagination (using a stable reference point — typically the last-seen item's ID or timestamp — rather than a numeric offset) avoids this and is the standard choice for any list endpoint expected to be large or under active write load.

Follow-up questions this topic invites — and their answers

Q: When is offset-based pagination actually fine despite its weakness? A: For small, relatively static datasets, or internal admin tooling where occasional skip/duplicate under concurrent writes is a minor, tolerable inconvenience rather than a correctness-critical issue — the cursor-based complexity isn't always worth paying for every list endpoint.

Q: How does API versioning interact with backward compatibility more generally? A: Versioning is the escape hatch for BREAKING changes; many changes (adding a new optional field, adding a new endpoint) don't need a new version at all if done in a backward-compatible way — over-relying on versioning for every change fragments the API into too many simultaneously-supported versions to maintain.

Q: Does an idempotency key need to be stored forever? A: No — typically stored with a bounded retention window (e.g. 24 hours) matching the realistic window in which a client might retry after a failure; after that window, the same key can be safely treated as a new request, keeping the idempotency-key store from growing unbounded.

Q: How would you decide between gRPC and REST for a NEW internal service, given the interoperability cost of switching later? A: Consider the team's existing tooling/expertise, the actual latency sensitivity of the calls involved, and whether the service might ever need to be called from outside the internal network (gRPC is less browser-friendly) — defaulting to REST unless there's a concrete, stated latency or throughput reason for gRPC is a reasonable, defensible interview answer.

Previous

Domain Decomposition

Next

Data Ownership Model

AI Tutor

Lesson: API Contract Design

Quick actions

AI responses can be inaccurate. Verify critical information.