Key Takeaways
- go android sms gateway api parse dlr is encoding/json over GET /api/v1/messages/{id} — not a branded Go SDK or module product.
- HTTP 202 on send means accepted. Status lives on the message object and on webhooks.
- Never overwrite Delivered with a late Pending. One precedence mapper for poll and push.
- Keys in env. Timeouts on the client. Docs win if this sample drifts.
- Priced by devices and SMS send volume. You use your own phone and operator SMS credit. Polling does not include operator airtime.
- Prefer webhooks in production; poll is a backfill.
net/http, not a Go SDK product
Search intent for go android sms gateway api parse dlr is mapping a JSON status into your domain — not installing a vendor module. Service pricing is based on device count and total SMS sent through the gateway. Live contract: docs.sms-gateway.app. Go’s own HTTP client is enough (net/http).
If your mapper treats every 2xx GET as Delivered, you are parsing HTTP, not DLR.
curl -X GET "https://app.sms-gateway.app/api/v1/messages/41822" \ -H "Authorization: Bearer $SMS_GATEWAY_API_KEY"
Same shape from Go:
package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
req, _ := http.NewRequest(http.MethodGet, os.Getenv("SMS_GATEWAY_DLR_URL"), nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SMS_GATEWAY_API_KEY"))
client := &http.Client{Timeout: 15 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(res.StatusCode, string(body))
}
That is copyable REST. It is not “Download Go SDK.” Send sibling: C# send (same REST).
GET /messages/{id}
Persist the id from the send response. Example accepted body (nothing has left the device yet):
{
"campaignId": 17,
"accepted": 1,
"scheduledAt": null,
"messages": [
{
"id": 41822,
"number": "+14155552671",
"text": "Your verification code is 481920",
"type": "sms",
"status": "Pending",
"campaignId": 17,
"deviceId": 3
}
]
}| Event | Store | Trap |
|---|---|---|
| Pending | Accepted / queued on device | Treat as success in the OTP UI |
| Delivered | Terminal success — do not regress | Late poll overwrites with Pending |
| Failed | Terminal fail — page radio/airtime | Immediate resend without Idempotency-Key |
| Webhook + poll | Same mapper; dedupe on message id | Two parsers that disagree |
Pending is not Delivered
Encode precedence in one function used by poll and webhook paths. Delivery reports.
Poll vs webhook reconciliation
Webhooks arrive at-least-once. Webhooks setup. Verify HMAC; dedupe on event id. Poll fills gaps — do not hammer GET.
Do not log the code
Log message id, masked MSISDN, status, latency. Strip Authorization. OTP verification. Priced by devices and SMS send volume. You use your own phone and operator SMS credit.
DLR mapper checklist
- net/http + env key; no fake SDK.
- Status enum from docs, not folklore.
- Delivered never regresses to Pending.
- Webhook + poll share one mapper.
- Staff canary before production OTP.
Next steps
Fetch one known id, map it, then subscribe. Pricing. Setup.
Related product pages
Jump to the live product docs for this topic—not another long-form article.
- SMS delivery reports (DLR)Delivery status tracking
- SMS API documentationLive endpoint reference
- device and SMS volume pricingPlans and allowances
- Android SMS gateway product guideDefinition, product, and how to buy





