API Contract

An API contract is the agreement between frontend and backend.

It defines:

Example contract

Create note:

POST /api/notes

Request:

{
  "title": "MongoDB notes",
  "body": "Learn schema design"
}

Success response:

{
  "data": {
    "id": "123",
    "title": "MongoDB notes",
    "body": "Learn schema design"
  }
}

Error response:

{
  "error": {
    "message": "Title is required"
  }
}

Frontend usage example

React code becomes simpler when the contract is stable:

async function createNote(input) {
  const response = await fetch('/api/notes', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(input),
  })

  const result = await response.json()

  if (!response.ok) {
    throw new Error(result.error.message)
  }

  return result.data
}

This works because the frontend knows:

Backend usage example

Express should intentionally return the same shape:

app.post('/api/notes', async (req, res, next) => {
  try {
    const note = await noteService.create(req.body)
    res.status(201).json({ data: note })
  } catch (error) {
    next(error)
  }
})

Why contracts matter

Without a contract:

Common mistake

Do not return different response shapes from similar endpoints.

If one endpoint returns { data } and another returns raw arrays, frontend code becomes messy.

Interview answer

An API contract defines how frontend and backend communicate: method, URL, request shape, response shape, errors, and status codes. A clear contract prevents frontend/backend mismatch and makes full-stack development easier to test and maintain.