A resend endpoint should be a small state machine, not a second login flow. For a healthtech marketplace seller signing in before viewing a new order, the useful contract is: one active code, a bounded resend window, an idempotent request key, and errors that tell the client what action is safe. The deciding constraint is integration effort. Put policy in one service, keep the Node.js transport adapter thin, and measure false rejects, delivery latency, and provider-independent outcomes before changing the policy.
Short answer: keep one active SMS OTP challenge, make resend idempotent, return explicit API errors for cooldown and expiry, and test those transitions before connecting a delivery provider.
Keep it boring.
How should SMS OTP API errors be handled?
The first implementation I usually see is a button that calls POST /otp/resend and generates another random value every time. I initially thought that was harmless.…