← Expedia Interview Insights

Expedia·Software Engineer·Onsite - System Design / Architecture·Senior

Senior
May 2026

Summary

System design round at Expedia for a software engineer role, centered entirely on designing a connectivity service that sits between external partners and an internal validation system. Pretty deep dive, they wanted actual HTTP specs not just hand-wavy architecture talk.

Questions Asked (6)

Q1

Design a REST API for a connectivity service that lets external partners create or update listings on your platform, including endpoint design, request/response payloads, required headers, authentication, and idempotency strategy.

API & IntegrationsSystem DesignTechnical Trade-offs
Author's notes

This is where I spent most of my time and honestly felt like I was playing catch-up.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements and assumptions (e.g., partner scale, listing schema, update frequency), then present a resource-oriented REST design with clear endpoints, payloads, and headers. Emphasize authentication (OAuth 2.0 client credentials), idempotency (Idempotency-Key header with server-side deduplication), and error handling to show production readiness.

Pro tip: Mention that idempotency keys should be scoped per partner and stored with the response for a TTL, and that you'd return the original response on retries—this demonstrates real-world API maturity.

1. Clarify requirements and assumptions

Ask about partner scale, listing attributes, update semantics (full replace vs. partial), and expected throughput. State assumptions to ground your design.

2. Design resource model and endpoints

Model listings as a collection under partners (e.g., /partners/{partnerId}/listings). Define POST for creation and PUT/PATCH for updates, with clear URL patterns and HTTP methods.

3. Specify request/response payloads and headers

Outline JSON schemas for listing creation/update, including required fields and validation. List required headers: Authorization, Content-Type, Idempotency-Key, and optionally Accept-Language or correlation ID.

4. Detail authentication and authorization

Use OAuth 2.0 client credentials flow for partner authentication, with scoped tokens (e.g., listings:write). Mention token validation and rate limiting per partner.

5. Explain idempotency and error handling

Describe idempotency strategy: clients send Idempotency-Key header; server stores key with response for a TTL and returns cached response on retry. Cover standard HTTP status codes and error payload structure.

Key Points to Mention

  • Resource-oriented URL design with proper HTTP methods (POST for create, PUT/PATCH for update)
  • OAuth 2.0 client credentials flow with scoped access tokens
  • Idempotency-Key header with server-side deduplication and TTL storage
  • Standard HTTP status codes (201 Created, 200 OK, 400 Bad Request, 401 Unauthorized, 409 Conflict, 429 Too Many Requests)
  • Consistent error response format with error codes and messages
  • Rate limiting and pagination for listing retrieval (if applicable)

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q2

Walk through the end-to-end flow from a partner sending a listing request to your service, through to the internal validation/domain service, and back to the partner with a result.

System DesignAPI & Integrations
Author's notes

I drew this out verbally and it went okay.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by framing the flow at a high level, then walk through each stage chronologically: partner request ingestion, API gateway and authentication, request validation and enrichment, domain service processing, and response construction and delivery. Emphasize idempotency, error handling, and observability at each step to show production maturity.

Pro tip: Mention idempotency keys and asynchronous processing with callbacks or polling for long-running validations—this shows you understand real-world partner integrations where retries and timeouts are inevitable.

1. Partner Request Ingestion

Describe how the partner sends the listing request (e.g., REST/JSON over HTTPS) and how it enters your system via an API gateway that handles authentication, rate limiting, and request logging.

2. Request Validation and Enrichment

Explain the initial validation layer: schema validation, required fields, and basic business rules. Mention enrichment steps like adding partner context or normalizing data before forwarding to the domain service.

3. Domain Service Processing

Walk through how the internal validation/domain service receives the request, performs deeper business validations (e.g., listing eligibility, duplicate checks), and persists or updates the listing state.

4. Response Construction and Delivery

Describe how the result is assembled (success with listing ID, or error with codes/messages) and returned to the partner synchronously or asynchronously via callback/webhook, including status codes and idempotency handling.

5. Observability and Error Handling

Highlight logging, metrics, and tracing across the flow, plus retry policies, dead-letter queues, and alerting for failures to ensure reliability and debuggability.

Key Points to Mention

  • Idempotency keys to handle duplicate partner requests safely
  • API gateway responsibilities: authentication, rate limiting, and request routing
  • Synchronous vs. asynchronous processing (callbacks/webhooks) for long-running validations
  • Error handling with standardized error codes and retry semantics
  • Observability: distributed tracing, logging, and metrics across services
  • Data validation at both API and domain layers to ensure integrity

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q3

How would you handle partner retries safely to avoid creating duplicate listings?

API & IntegrationsTechnical Trade-offs
Author's notes

Idempotency keys stored server-side with a TTL.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by emphasizing idempotency as the core principle: every retry must be safe to execute multiple times without side effects. Then describe a concrete mechanism like idempotency keys combined with deduplication checks at the database or service layer, and explain how you'd handle edge cases such as partial failures and concurrent retries.

Pro tip: Mention that idempotency must be enforced at the persistence layer (e.g., unique constraints or conditional writes), not just in application logic, because distributed retries can race. Also note that you'd log and monitor duplicate-attempt metrics to catch gaps in your idempotency coverage.

1. Define idempotency contract

Explain that each partner retry must carry a unique idempotency key (e.g., partner ID + request ID) so the server can recognize repeated attempts. Clarify that the key must be generated by the partner or derived deterministically from the request payload.

2. Enforce deduplication at write time

Describe using a database unique constraint or conditional write (e.g., INSERT ... ON CONFLICT DO NOTHING) on the idempotency key to atomically reject duplicates. This ensures safety even under concurrent retries.

3. Handle partial failures and response replay

Explain that if the first attempt succeeded but the response was lost, the retry should return the original result (or a cached response) rather than creating a new listing. Store the outcome keyed by the idempotency key for a reasonable TTL.

4. Address concurrency and race conditions

Mention that two simultaneous retries with the same key must not both create listings; use transactions, row locks, or a distributed lock to serialize the check-and-create operation.

5. Monitor and test

Describe adding metrics for duplicate attempts and writing integration tests that simulate retries, timeouts, and concurrent requests to verify no duplicates are created.

Key Points to Mention

  • Idempotency keys (partner-provided or derived deterministically)
  • Database unique constraints or conditional writes for atomic deduplication
  • Caching and replaying the original response for repeated requests
  • Handling concurrent retries with transactions or distributed locks
  • TTL and cleanup strategy for idempotency records
  • Monitoring duplicate-attempt rates and testing retry scenarios

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q4

How does your service stay resilient when the internal validation/domain service is slow or unavailable?

System DesignTechnical Trade-offs
Author's notes

Circuit breaker pattern, queue-based buffering, retries with backoff.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying that resilience is about graceful degradation, not just uptime, and describe a layered strategy: timeouts, circuit breakers, fallbacks, and async decoupling. Then walk through a concrete example from your experience, emphasizing trade-offs like consistency vs. availability and how you validated the approach with metrics and chaos testing.

Pro tip: Frame resilience as a product decision: explain how you chose fallback behavior (e.g., fail-open vs. fail-closed) based on business impact, and mention that you'd align with product owners on acceptable degradation—this shows senior-level thinking beyond pure engineering.

1. Define the failure modes and impact

Briefly classify what 'slow' and 'unavailable' mean for the validation service (latency spikes, timeouts, partial failures) and the downstream business impact (e.g., booking flow blocked vs. degraded).

2. Apply defensive patterns at the call site

Describe timeouts, retries with backoff and jitter, circuit breakers, and bulkheads to prevent cascading failures and thread pool exhaustion.

3. Design fallback and degradation paths

Explain cached/stale validation results, default-allow or default-deny policies, and async validation with reconciliation, tying each to the business trade-off.

4. Decouple with async and queueing where possible

Mention event-driven validation, outbox patterns, or queue-based retries so the main flow isn't blocked by the domain service.

5. Validate and observe

Close with how you'd prove resilience: SLOs, circuit breaker metrics, chaos/fault-injection tests, and load tests simulating slow dependencies.

Key Points to Mention

  • Timeouts, retries with exponential backoff and jitter, and circuit breakers to prevent cascading failures
  • Fallback strategies (cached/stale data, default policies) and the consistency vs. availability trade-off
  • Bulkheads and thread pool isolation to contain the blast radius
  • Asynchronous validation or queue-based decoupling for non-blocking flows
  • Observability: metrics, alerts, and SLOs on dependency latency and error rates
  • Chaos engineering or fault injection to test resilience before production incidents

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q5

What HTTP status codes would your API return, and under what conditions would each apply?

API & IntegrationsTechnical Trade-offs
Author's notes

200 for sync success, 201 for created, 202 for async accepted, 400 for schema/validation failures at the edge, 401/403 for auth, 409 for conflicts, 429 for rate limiting, 503 when downstream is down.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by grouping status codes into categories (2xx, 3xx, 4xx, 5xx) and give a representative example for each, tying them to concrete API scenarios like resource creation, validation failures, or server errors. Emphasize that the choice of codes should be consistent, documented, and driven by client needs—especially for a travel platform where partial failures and idempotency matter.

Pro tip: Mention that for a travel API, 409 Conflict is often more appropriate than 400 for booking collisions, and that 207 Multi-Status or a custom error envelope can handle partial success in multi-item requests—showing you think beyond textbook answers.

1. Categorize by class

Briefly outline the 2xx, 3xx, 4xx, and 5xx families and state the principle that each code must have a clear, documented meaning.

2. Map success codes to operations

Give examples like 200 OK for GET/PUT, 201 Created with Location header for POST, and 204 No Content for DELETE.

3. Cover client error scenarios

Explain when to use 400 (malformed request), 401 vs 403 (authentication vs authorization), 404 (missing resource), 409 (conflict like double booking), and 422 (semantic validation errors).

4. Address server and infrastructure codes

Describe 500 for unhandled exceptions, 503 for maintenance or overload, and 429 for rate limiting with Retry-After header.

5. Discuss consistency and trade-offs

Explain how you would document codes in an OpenAPI spec, use a consistent error response body, and decide between 400 vs 422 or 409 vs 400 based on team conventions.

Key Points to Mention

  • 201 Created with Location header for resource creation
  • 401 Unauthorized vs 403 Forbidden distinction
  • 409 Conflict for booking collisions or duplicate requests
  • 422 Unprocessable Entity for semantic validation failures
  • 429 Too Many Requests with Retry-After header
  • Consistent error response schema and OpenAPI documentation

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q6

How would you design observability into this service, covering metrics, logging, and distributed tracing?

System DesignTechnical Trade-offs
Author's notes

Standard stuff: request latency, error rates per partner, downstream call durations, queue depth if async.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the service's critical user journeys and SLOs, then propose a unified observability strategy that ties metrics, logs, and traces together via correlation IDs. Walk through each pillar with concrete tooling choices and trade-offs, emphasizing how they enable faster debugging and proactive alerting.

Pro tip: Anchor your answer in SLOs and error budgets—showing you design observability to answer 'is the user happy?' rather than just 'is the CPU busy?' demonstrates senior-level thinking.

1. Define SLOs and critical paths

Identify the key user journeys and establish SLIs/SLOs (e.g., latency, error rate) to guide what to instrument and alert on.

2. Instrument metrics with RED/USE

Use RED (Rate, Errors, Duration) for request-driven services and USE (Utilization, Saturation, Errors) for resources; expose via Prometheus/OpenTelemetry and set up dashboards and alerts.

3. Implement structured logging with correlation

Emit structured JSON logs with consistent fields (trace_id, user_id, request_id) and centralize them (e.g., ELK, Loki) for querying and correlation with traces.

4. Add distributed tracing with context propagation

Use OpenTelemetry to instrument inbound/outbound calls, propagate trace context across services, and sample intelligently (e.g., head-based with tail-based sampling for errors).

5. Unify and iterate

Correlate all three pillars in a single pane (e.g., Grafana, Datadog), define alerting thresholds based on SLOs, and continuously refine instrumentation based on incidents.

Key Points to Mention

  • SLOs/SLIs and error budgets as the foundation for observability
  • OpenTelemetry for vendor-neutral instrumentation of metrics, logs, and traces
  • Structured logging with trace_id correlation for cross-pillar debugging
  • Trace context propagation (e.g., W3C Trace Context) across service boundaries
  • Sampling strategies (head-based vs. tail-based) to balance cost and visibility
  • Alerting on symptoms (SLO burn) rather than causes (CPU) to reduce noise

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.