Grokking Modern API Design Interview
Vote

0% completed

​

What Interviewers Actually Grade

  1. Signal One: Start from the Caller and the Job

What a weak answer sounds like

What a strong answer sounds like

  1. Signal Two: Create a Consistent Model

What a weak answer sounds like

What a strong answer sounds like

  1. Signal Three: Design Failures, Not Just Successes

What a weak answer sounds like

What a strong answer sounds like

  1. Signal Four: Plan for Change

What a weak answer sounds like

What a strong answer sounds like

  1. Signal Five: State Trade-offs Aloud

What a weak answer sounds like

What a strong answer sounds like

  1. Which Signals Affect the Rating Most?
  1. The Most Common Failure: Turning Tables into URLs

Why this pattern fails

The stronger direction

  1. Make the Scorecard Visible

Key Takeaways

An interviewer can evaluate your design only if you explain it.

Show your reasoning through the questions you ask, the model you draw, the operations and errors you define, and the alternatives you compare.

Experience alone does not communicate your design decisions. A candidate with a reasonable design may give a weak answer if they leave the reasoning unexplained. A different design can also be strong when its choices and disadvantages are clear.

The scorecard is not mainly about remembering HTTP vocabulary. It is about five signals:

  1. You start from the caller and the job.
  2. You create a consistent model.
  3. You design failures as part of the contract.
  4. You plan for change.
  5. You state trade-offs aloud.

Companies use different evaluation criteria. This course uses these five skills to organize your preparation.

Each section compares a weak answer with a stronger one. Section 6 explains how to prioritize these skills when time is limited.

1. Signal One: Start from the Caller and the Job

This signal appears before you draw a resource or name an operation. Who will call this API, and what are they trying to finish?

A mobile application, a partner integration, an internal service, and a script may share one underlying service and still need different contracts. The mobile client wants one compact response for a weak network. The partner wants stable resources, explicit limits, and long deprecations. The internal service wants throughput, idempotent writes, and machine-readable failures.

What a weak answer sounds like

"We have users, orders, and order items in the database, so I'll create endpoints for those tables."

The storage model was chosen before the caller's job. "I'll use REST. We need GET, POST, PUT, and DELETE" is the same failure: neither says what the caller is trying to accomplish.

What a strong answer sounds like

"Who are the main consumers? Is this API used by our checkout application, external merchants, or both?"

Then:

"For the first-party checkout client, the two important jobs are creating an order and showing its current state. I'll design around those jobs first."

The strong answer does not gather every possible requirement. It identifies enough context to make the next decision correctly.

2. Signal Two: Create a Consistent Model

Consistency makes an API learnable. After seeing two operations, a caller should predict the third. If one collection returns next_cursor, every cursor-paginated collection uses that field. If errors carry error.code, the next operation does not return a free-form reason.

Use consistent naming, URL structure, field casing, identifiers, units, list responses, pagination, error bodies, filtering, and sorting. The goal is to make behavior easier for clients to predict, not just to make the API look organized.

What a weak answer sounds like

"To get a user, call GET /user?id=123. To get a project, call POST /projects/get with projectId. To get a task, call GET /tasks/123."

Each may work, but the caller learns a new pattern every time. Are reads GET or POST? Are identifiers in the path, query, or body? Every inconsistency becomes documentation to read and code to special-case.

What a strong answer sounds like

"I'll use plural collection paths and place the resource identifier in the path: GET /users/{user_id}, GET /projects/{project_id}, and GET /tasks/{task_id}. Collection operations will use the same cursor envelope and error shape."

The important part is not that plural nouns are correct. It is that the contract has a rule and the rule still applies to the next operation.

The prediction test: if the interviewer saw two examples, could they guess the shape of the third? If not, either the model is inconsistent or an exception needs explaining.

3. Signal Three: Design Failures, Not Just Successes

A contract is incomplete until the caller knows what can go wrong, because different failures require different actions:

  • malformed input should be fixed before retrying;
  • missing authentication requires new credentials;
  • insufficient permission may require a different user or scope;
  • a conflict may require fresh state;
  • a rate limit may require waiting; and
  • a temporary server failure may be safe to retry.

If every failure becomes 500 Internal Server Error, the caller cannot respond correctly.

What a weak answer sounds like

"On success, I'll return the object. Otherwise, I'll return an error."

The word "error" leaves every decision unmade. "400 for anything the client did wrong and 500 for everything else" is better, but a program still cannot separate a missing field from a conflict, an expired credential, or a rate limit.

What a strong answer sounds like

"Creation has four caller-visible failures: 400 when the request cannot be parsed or a required field is missing, 404 when the referenced project does not exist, 409 when the requested unique key already belongs to another resource, and 429 when the caller exceeds its write limit. Every failure uses the same machine-readable body."

{ "error": { "code": "duplicate_external_id", "message": "A task with this external ID already exists.", "field": "external_id", "request_id": "req_7f91" } }

The message helps a developer understand the problem. Programs use the stable code to decide what to do. The field identifies a relevant input, and the request_id helps support staff find the request in logs. Document that clients should not make decisions based on the wording of message.

Status codes affect client behavior. Clients, SDKs, gateways, monitoring tools, and retry systems use them to interpret results. Returning 500 for invalid input may cause useless retries. Returning 400 for a rate limit without retry guidance may cause a client to stop instead of waiting.

4. Signal Four: Plan for Change

The API you design in the interview is version one, even if the question does not say so. The interviewer wants evidence that version two can exist without breaking version one's callers. Be ready to explain three changes.

Adding a field. Usually compatible if callers ignore what they do not recognize, but an added field is not automatically safe: a field can increase payload size, expose sensitive data, or change caching. State the expectation that clients ignore unknown fields. In requests, an optional field with a default is far easier than a required one, which breaks every existing caller.

Adding an operation. Normally additive, since existing callers do not invoke it, provided it follows the existing naming, error, and pagination patterns. The harder question is whether it should be a new operation or a flag on an existing one. Many flags create combinations nobody can reason about.

Removing something. This follows from the permanence rule in Lesson 2: mark it deprecated, name the alternative, give notice, measure usage, and support both during the migration window. Some callers will not migrate on time. Removal is a coordination process, not only a code change.

What a weak answer sounds like

"If the API changes, we'll create /v2."

Versioning may be necessary, but this postpones the problem. What changed? Why was an additive change impossible? Does every field addition need a new version?

"This is an internal API, so we can change it whenever we want" is also weak. Internal callers are easier to find, but other teams deploy on their own schedules, and old jobs stay in production.

What a strong answer sounds like

"I'll make response evolution additive: clients ignore unknown fields, and new request fields are optional with documented defaults. If we must replace the state model with incompatible semantics, I would introduce the new representation alongside the old one, deprecate the old field, publish the translation, measure usage, and remove it only after the migration window."

5. Signal Five: State Trade-offs Aloud

API design questions rarely have one correct answer. For example, should creation return the full resource or only its ID? Should a client check the status of long-running work or receive a webhook? Explain your choice, the alternative, the benefit, and the cost.

What a weak answer sounds like

"I'll use cursor pagination."

It may be the right choice, but the interviewer cannot tell whether the candidate understands it. "Cursor pagination is better" is worse: better for what?

What a strong answer sounds like

"I'll use cursor pagination instead of page numbers because new records are inserted frequently. Continuing after a stable sort key avoids shifts caused by numeric offsets. It does not guarantee a fixed snapshot if records change. Clients also cannot jump directly to page 20, and they must treat the cursor as an opaque value."

You can explain a trade-off briefly. Use this pattern to connect the choice to a requirement:

"I chose A instead of B because this caller needs benefit. The cost is cost, which I accept because requirement."

6. Which Signals Affect the Rating Most?

There is no universal point system. Companies, roles, and interviewers use different rubrics. Still, the signals affect the conversation in different ways.

When practicing, pay particular attention to these three parts of your answer:

  1. Your opening: do you begin with the caller and job?
  2. Your complete operation: do you design both success and failure?
  3. Your decision statements: do you compare alternatives and name costs?

Consistency matters throughout the answer. Planning for change also shows that you consider the API beyond its first release. None of the five skills should be ignored. The three parts above are useful priorities when time is short, not a universal scoring system.

Five skills to demonstrate: understand client tasks, define failures, explain trade-offs, use a consistent model, and plan for change. Use the opening, the detailed operation, and the comparison of alternatives to explain your reasoning. Companies may evaluate these skills differently.
Five skills to demonstrate: understand client tasks, define failures, explain trade-offs, use a consistent model, and plan for change. Use the opening, the detailed operation, and the comparison of alternatives to explain your reasoning. Companies may evaluate these skills differently.

7. The Most Common Failure: Turning Tables into URLs

A common weak approach is to turn every database table directly into an API resource without checking what clients need.

Imagine that a project-management service stores data in these tables:

projects tasks task_assignees task_comments task_status_history

A database-first API might expose one collection for each table:

/projects /tasks /task_assignees /task_comments /task_status_history

This approach looks organized, but it can leave too much work for the client. A task screen may need to fetch a task, assignments, user details, comments, and status history separately, then combine them. The API reflects how data is stored rather than how the screen uses it.

Why this pattern fails

  • It exposes implementation details. The caller learns which relationships are join tables, so a storage change makes the contract misleading.
  • It increases call count. One screen may require many sequential requests, and each round trip adds visible latency on a mobile network.
  • It publishes operations no caller needs. Table-level CRUD creates a larger contract to secure and preserve.
  • It weakens authorization. "Can this user assign this task?" is clearer than granting generic write access to an assignment-row endpoint.
  • It makes storage migration expensive. If the team removes a join table or moves comments to another service, callers should not have to migrate.

The stronger direction

Start with the jobs: create a task, view one with what its screen needs, assign a person, comment, view activity. Then model Project, Task, Comment, and ActivityEntry. The server may still use the five original tables; the API does not promise that layout.

GET /v1/tasks/tsk_123
{ "id": "tsk_123", "title": "Prepare launch checklist", "status": "in_progress", "assignees": [ { "id": "usr_17", "display_name": "Ari Chen" } ], "comment_count": 8, "updated_at": "<RFC 3339 UTC timestamp>" }

This response provides the data needed for a common task view. Comments and activity remain separate, paginated resources because those lists can be large. Choose the API structure based on client tasks and response size, not simply on database tables.

A database-first design may force clients to combine many small responses and depend on storage details. Starting with client tasks helps you define useful resources and operations while keeping the storage implementation separate.
A database-first design may force clients to combine many small responses and depend on storage details. Starting with client tasks helps you define useful resources and operations while keeping the storage implementation separate.

8. Make the Scorecard Visible

You do not need to announce every signal by name. Use short sentences that create evidence naturally.

One sentence you can say aloud for each of the five graded signals, so the evidence reaches the interviewer without a speech: the caller and job, consistency, failures, change, and the trade-off with its cost.
One sentence you can say aloud for each of the five graded signals, so the evidence reaches the interviewer without a speech: the caller and job, consistency, failures, change, and the trade-off with its cost.

These short statements make the reasons for your design choices clear.

Key Takeaways

  • Interviewers usually look for five signals: caller-first thinking, consistency, designed failures, change planning, and explicit trade-offs.
  • Starting from the caller matters most because a well-structured contract can still solve the wrong job.
  • Consistency is a product feature: after two operations, a caller should predict the third.
  • Failures need correct status codes and stable machine-readable bodies so programs can choose the next action.
  • Explain how to add a field, add an operation, and remove something without surprising existing callers.
  • A trade-off becomes visible when you name the option, the alternative, the benefit, and the cost.
  • Turning database tables directly into URLs creates extra calls, exposes the storage layout, weakens product semantics, and makes future migrations expensive.

You now know which parts of your reasoning to explain. The next lesson organizes them into the course's six-step method, with suggested time allocations for 45-minute and 30-minute interviews.

Reading Progress

0%


Vote for new content

On This Page

  1. Signal One: Start from the Caller and the Job

What a weak answer sounds like

What a strong answer sounds like

  1. Signal Two: Create a Consistent Model

What a weak answer sounds like

What a strong answer sounds like

  1. Signal Three: Design Failures, Not Just Successes

What a weak answer sounds like

What a strong answer sounds like

  1. Signal Four: Plan for Change

What a weak answer sounds like

What a strong answer sounds like

  1. Signal Five: State Trade-offs Aloud

What a weak answer sounds like

What a strong answer sounds like

  1. Which Signals Affect the Rating Most?
  1. The Most Common Failure: Turning Tables into URLs

Why this pattern fails

The stronger direction

  1. Make the Scorecard Visible

Key Takeaways