Knowledge check
Webhook Architecture
12 questions in pool · live exam draws 5
I02
Q1 multiple-choice · polling-vs-webhook When should you choose webhooks over polling for a PhotoRobot integration?
Source: I02 textbook §1 (When to use webhooks vs. polling).
Explanation: Webhooks win for real-time + low-event-rate-vs-poll-rate scenarios . Polling wins for very-low-event-rate (nightly is fine), or environments that can’t expose inbound HTTPS. The honest answer is most integrations should start with polling — graduate to webhooks only when polling becomes painful. Don’t add webhook complexity just because they sound modern.
Q2 scenario · receiver-anatomy · weight 2 You’re building a webhook receiver for a customer integration. List the 5 sequential steps every correct receiver does before processing the event.
Source: I02 textbook §3 (The webhook receiver — anatomy of a correct endpoint).
Explanation: The canonical correct sequence: (1) signature verification, (2) timestamp verification (replay protection), (3) idempotency check, (4) fast acknowledgment, (5) async enqueue . Skipping any one turns the integration into a ticking time bomb. Most webhook bugs trace to missing one of these.
Q3 multiple-choice · hmac-comparison When verifying a PhotoRobot webhook HMAC signature, which comparison method should you use?
Source: I02 textbook §4 (Computing the expected signature).
Explanation: Constant-time comparison is required. Plain == leaks information about how many bytes match via timing side-channels — an attacker can iterate byte-by-byte and forge a valid signature in finite tries. Constant-time compare always takes the same time regardless of how many bytes match, denying the attacker that signal. Every language’s crypto library provides one — use it.
Q4 multiple-choice · replay-window PhotoRobot’s recommended timestamp tolerance window for webhook replay protection is:
Source: I02 textbook §6 (Replay protection — defending against captured webhooks).
Explanation: ±5 minutes is the standard tolerance. Too short (< 1 min) → production load spikes cause legitimate webhooks to age out before processing. Too long (> 1 hour) → captured webhooks remain replayable for too long. 5 minutes is long enough for PhotoRobot retry + your queue depth, short enough that captured replays are limited.
Q5 scenario · idempotency-layers · weight 2 Your webhook receiver dedups by event ID. Despite this, customers report duplicate uploads in their DAM after webhook retries.
Source: I02 textbook §5 (Idempotency at the side-effect level).
Explanation: Two layers of idempotency are required: (1) receiver dedups by event ID (prevents duplicate processing of the same delivery attempt), (2) downstream side effects are themselves idempotent (UPSERT, idempotency keys, item-ID-keyed assets). If receiver dedup works but the DAM still gets duplicates, side-effect layer is missing — fix by keying DAM assets by item ID instead of generating new asset IDs per upload.
Q6 multiple-choice · ack-timing PhotoRobot expects a 200 OK response from your webhook handler within approximately:
Source: I02 textbook §7 (Acknowledgment + async processing).
Explanation: PhotoRobot’s webhook delivery timeout is ~10 seconds . Recommended: handler returns 200 in < 2 seconds — gives headroom for unexpected latency. Beyond 10 seconds, PhotoRobot assumes failure and retries. Your handler must do the minimum work synchronously (signature + timestamp + dedup + enqueue) and process async via queue.
Q7 scenario · signature-failure · weight 2 Your webhook receiver suddenly starts returning 401 Invalid Signature for every delivery, even though the secret hasn’t changed.
Source: I02 textbook §4 (Common signature verification pitfalls) + §13 (Common failure modes).
Explanation: The body must be in raw bytes when computing the HMAC verification — the same bytes PhotoRobot signed. If middleware (e.g., express.json()) parses the body before your verification, the bytes are different (whitespace normalized, JSON re-stringified) and the HMAC fails. Fix: capture raw body BEFORE any JSON / URL-encoded parser. Most common: forgetting express.raw({ type: 'application/json' }) and using express.json() directly.
Q8 multiple-choice · secret-storage Where should a PhotoRobot webhook signing secret be stored?
Source: I02 textbook §2 (Storing the signing secret).
Explanation: Webhook signing secrets follow the same discipline as API keys — secrets vault, server-side only, never in code, never logged. PhotoRobot shows the secret once at subscription creation; if lost, you must rotate (create new subscription + migrate). Treat it like an API key, because it is the key that defends against forged webhook events.
Q9 scenario · queue-choice · weight 2 A junior engineer on your team builds a webhook handler that processes events inline using an in-memory Node.js EventEmitter queue. The handler often takes 5-15 seconds because it calls a downstream API.
Source: I02 textbook §7 (Acknowledgment + async processing) + §13 (Common failure modes).
Explanation: Two anti-patterns at once: (1) inline processing > 10s → PhotoRobot retries → duplicate processing (unless idempotent at side-effect layer, this duplicates downstream calls); (2) in-memory queue loses pending events on crash. Both are textbook reasons to use a durable queue + fast acknowledgment + async worker . Junior implementations often skip both because “it’s only a few seconds” — until production load + a downstream slowdown surface the cascade failure.
Q10 multiple-choice · dedup-retention How long should you retain the dedup record (event_id → processed flag) after first seeing an event?
Source: I02 textbook §5 (Retention period).
Explanation: PhotoRobot retries with exponential backoff for up to ~24 hours after the first delivery attempt. 48 hours of retention in your dedup store gives comfortable margin. After 48 hours, if the same event_id arrives again (it shouldn’t), processing it again is safer than blocking — and should fire an alert because it indicates either an unusual retry pattern or a delivery system bug. “Forever” is wasteful and creates unbounded storage growth.
Q11 true-false · back-pressure If your webhook receiver is overwhelmed by traffic spikes, you should return 200 OK to prevent retries and absorb the spike silently.
Source: I02 textbook §12 (Webhook delivery failures + back-pressure).
Explanation: False — opposite of correct. Return 503 Service Unavailable to signal back-pressure honestly. PhotoRobot’s retry with backoff will replay the events when you recover. Returning 200 to “avoid retries” silently drops events — you’ve now lost data the customer expects to flow. The correct discipline is to let your queue absorb spikes (workers drain at sustained rate) and return 503 if your queue is full so PhotoRobot’s retry mechanism preserves the events.
Q12 scenario · reconciliation-poll · weight 2 Your webhook integration was misconfigured for 6 hours, returning 500 errors. PhotoRobot retried, but eventually entered degraded state and stopped delivering. You’ve fixed the bug and re-enabled the subscription.
Source: I02 textbook §12 (Subscription paused or disabled) + §1 (Hybrid pattern).
Explanation: Reconciliation poll is the recovery pattern. Query the REST API for items modified since the last successful webhook delivery. Because your handler is idempotent (per textbook §5), duplicates from any overlapping events are harmless. This is also why textbook §1 recommends hybrid pattern — webhooks for fast path + nightly reconciliation for safety net. Outages happen; reconciliation guarantees eventual consistency.
Ready to commit? You can review and change your answers before submitting. Once submitted, this attempt is final and we'll show you your score, correct answers, and explanations.
Submit final answers