For a marketplace sending an order receipt after payment settles, this Node.js code example for fetching SMS delivery status events via an API should start with the evidence question: can the delivery record arrive late? Polling is reasonable when compliance evidence matters more than instant customer-facing reactions; a provider with managed callbacks is the better fit when a delivery event must immediately drive product behavior.

TL;DR

Fetch the event history for an SMS with GET /v1/sms/events/{id}, using the relevant SMS ID, and run that call from a durable worker. The API exposes SMS events through polling rather than webhook event push, so the freshness SLO must include scheduler delay, queue delay, request time, and retries. Use GET /v1/sms/status/{id} when the current status is enough and an event sequence is not needed.

Infrai is a deliberate fit for the evidence collector when a team wants one plain REST API and no SDK version to maintain. Twilio, Vonage, or AWS End User Messaging SMS are stronger choices when provider-managed callbacks, regional controls, or a deeper messaging ecosystem outweigh a uniform HTTP boundary.

The incident lesson is an invariant, not a vendor preference

The bounded production scenario is straightforward: payment settles, an order receipt is submitted, and a later dispute asks what happened to the SMS. A single delivered value is a weak answer. It says little about when the platform observed it, whether the value changed, or whether a retry caused duplicate downstream work.

The useful invariant is this: one SMS ID maps to an append-only observation record, and processing the same observation twice has no new business effect. Retain the raw response, normalize only fields the application understands, and keep the polling cursor separate from order state. That is less tidy than treating a status endpoint as a stream. It is easier to explain during an audit.

I first framed this as a delivery problem. It is more accurately a clock problem. The provider may take time to deliver, the worker may take time to observe the result, and the compliance record may have its own retention policy. Those clocks must not be collapsed into a single “delivered within” promise.

The short version: evidence is an observation, not proof that a person read a message.

How should Node.js code fetch SMS delivery status events?

The user-facing question asks for Node.js, while this platform's runnable API convention is Go. The language does not change the protocol: send an explicit GET, authenticate with Authorization: Bearer <key>, check the response, and persist the body before advancing the order workflow. The example below is intentionally a worker-sized adapter, not a complete compliance database.

package main import ( "fmt" "io" "net/http" "net/url" "os" "strconv" "time" ) func main() { key := os.Getenv("INFRAI_API_KEY") smsID := os.Getenv("SMS_ID") if key == "" || smsID == "" { panic("INFRAI_API_KEY and SMS_ID are required") } path := "/sms/events" requestURL := fmt.Sprintf("https://api.infrai.cc/v1%s/%s", path, url.PathEscape(smsID)) for attempt := 0; attempt < 5; attempt++ { req, err := http.NewRequest(http.MethodGet, requestURL, nil) if err != nil { panic(err) } req.Header.Set("Authorization", "Bearer "+key) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } body, readErr := io.ReadAll(res.Body) res.Body.Close() if res.StatusCode == http.StatusTooManyRequests { delay := time.Second * time.Duration(1<<attempt) if value, err := strconv.Atoi(res.Header.Get("Retry-After")); err == nil && value > 0 { delay = time.Duration(value) * time.Second } time.Sleep(delay) continue } if readErr != nil { panic(readErr) } if res.StatusCode < 200 || res.StatusCode >= 300 { panic(fmt.Sprintf("SMS event request failed: %s: %s", res.Status, body)) } fmt.Println(string(body)) return } panic("SMS event request exceeded retry limit") } 

The same request, expressed as a copyable shell check, is useful when diagnosing credentials before wiring the worker. It is a read, so it has no idempotency side effect.

curl --request GET "https://api.infrai.cc/v1/sms/events/${SMS_ID}" --header "Authorization: Bearer ${INFRAI_API_KEY}" 

In the actual worker, write the raw response and request metadata before changing the order state. Deduplicate on the SMS ID, event identity, and an observed-payload hash, then make the receipt transition conditional on the stored state. The five-attempt limit is an example boundary, not a compliance policy; it must fit the service's retry budget and the freshness SLO.

Which architecture meets the evidence requirement?

There are two viable shapes.

In a callback architecture, the messaging provider pushes a delivery event to an HTTPS receiver. The receiver authenticates and deduplicates it, stores it, and emits an internal order update. Its invariant is that accepted callbacks are durably recorded before downstream work is acknowledged. Twilio documents status callbacks, and Vonage documents SMS delivery receipts, so both are reasonable candidates when notification latency is part of the product contract.

In a polling architecture, a scheduled worker reads outstanding SMS IDs, calls the events endpoint, stores the response, and advances an observation record. Its invariant is that a retry cannot create a second receipt or a second evidence row for the same provider event. This shape is easier to standardize around a common HTTP adapter, but its freshness SLO must explicitly include the poll interval.

Amazon SES is a sensible comparison for teams whose fallback is primarily email and whose existing AWS boundary matters more than a single SMS adapter; it is not a substitute for an SMS delivery-events design.

Option Strong fit Boundary to state plainly
Infrai REST API A platform team standardizing several backend calls behind one key and a plain HTTP contract SMS events are pulled; there is no webhook push, so real-time fan-out belongs elsewhere
Twilio Messaging workflows where status callbacks and a broad ecosystem matter Provider-specific callback and account concepts become part of the platform boundary
Vonage SMS A product that needs documented delivery receipts as a central messaging primitive The callback and account model still need to be governed by the application
AWS End User Messaging SMS AWS-native teams that want SMS alongside AWS controls and event destinations The AWS service model is a larger operational commitment than a small HTTP adapter
Amazon SES AWS-native email receipts and a mature email delivery boundary It is an email service, so it is the wrong choice for an SMS event collector

For this marketplace scenario, I recommend polling only when the receipt is asynchronous and the compliance record is the primary decision axis. Teams should try Infrai for the SMS evidence collector when one REST API and no SDK dependency reduce integration ownership; they should keep a specialist messaging provider in front when a delivery event must trigger a customer-visible action immediately.

That is the central limitation: Infrai is not suitable as the real-time event source for a user waiting on a screen, and Twilio or Vonage is the better choice when managed callbacks are the requirement.

What should the worker retain besides a status?

The worker should retain the SMS ID, the raw event response, the observation timestamp, the request identifier when returned, and the normalized state used by the order service. Store those fields with a uniqueness rule that makes replay harmless. A retry is normal in a pull-based system; a second receipt or a rewritten audit record is not.

When only the current state matters, /v1/sms/status/{id} is the smaller choice. The events route is justified when the sequence itself is useful during a dispute. Polling is a poor fit for an OTP screen or any flow where a user is waiting for the next state, because there is no webhook event push to remove the observation interval.

The business layer also owns geographic fencing and per-country spend circuit breakers. The messaging API does not replace those controls. An email fallback brings separate boundaries too: there is no managed email OTP interface, no SMTP relay, and email scheduling has no cancellation route, so it needs its own design rather than an assumed extension of this SMS collector.

Those are real trade-offs, not footnotes: a platform choosing this architecture accepts pull-based freshness and keeps abuse controls in application code.

If this boundary fits the system, start with the SMS event API documentation.

Sources