Building Reliable Integrations
Four practical rules cover almost every reliability question that comes up against this API.
What idempotency actually covers
Pass your own request_id on /api/v1/sms/send/. Replaying the same value from the same account within 24 hours returns the original message instead of creating a new one — this is the only idempotency guarantee Connecfy makes, and it applies to that one endpoint. There's no idempotency key support on any other endpoint, so don't assume, say, retrying a status check or a device-status callback has special duplicate-safety beyond what's described for each in Errors.
Without a request_idEvery call to /sms/send/ creates a new message, full stop. If you don't pass one, a retried request sends twice. This is the single most common integration mistake against this API — always generate one if there's any chance your own code might call send more than once for the same logical message.
Retrying transient failures
A network timeout or a 5xx on your end talking to Connecfy means you don't know whether the request landed — retry it, with the same request_id, so a request that did land doesn't become a duplicate send. Back off between attempts (a second or two, doubling, capped at something reasonable) rather than retrying in a tight loop, and respect Retry-After on a 429 exactly — see Rate Limits.
Avoiding accidental duplicate sends
Beyond network retries, the other common source of duplicates is application logic — a queue consumer that redelivers a job, a user double-clicking submit. The fix is the same: derive request_id from something stable in your own system (the job id, the order id) rather than generating a fresh random one per attempt, so two attempts at "the same" send collapse into one.
Monitoring status without a webhook
Since nothing is pushed to you, checking status is a job you run. A reasonable pattern: after queuing, wait ~20 seconds before the first check (matching the poll cycle in How Connecfy Works), then poll every 15–20 seconds until you see sent, delivered, or failed, with a sensible cutoff (a couple of minutes) after which you stop polling and treat it as needing manual attention. Polling faster than the underlying ~20-second cycle just spends your rate limit for no new information — see Rate Limits.
Handling your own timeouts
Set a client-side timeout on calls to Connecfy that's generous enough to not fire on ordinary latency — a few seconds is reasonable for the send endpoint, since it only needs to write a queue row, not wait on a phone. If a call does time out, treat it exactly like a transient failure: retry with the same request_id.