Most SMS gateway providers expose a simple HTTP REST API: you POST a form-encoded payload with your sender address, recipient number, and message body, and the gateway delivers the SMS. This post shows how to wire that up in VB.NET using HttpWebRequest, including Basic authentication and error handling for protocol-level failures.
The endpoint and credentials below are placeholders. Substitute the URL, username, and password supplied by your own gateway provider. The structure of the request is the same across most providers that use form-encoded POST APIs.
The subroutine accepts a sender number, a recipient number, and the message text. It builds a form-encoded POST body, attaches a Basic Authorization header using the gateway credentials, writes the body to the request stream, and shows a confirmation or error message depending on the response.
Sub SendSMS(ByVal FromNumber As String, ByVal ToNumber As String, ByVal message As String)
Try
'SMSified API endpoint
'the url is given by the gateway provider
webTarget = "http://api.xyz.com/"
'Parameters to send with API request
post_data = "address=" & ToNumber & "&senderaddress=" & FromNumber & "&message=" & HttpUtility.UrlEncode(message)
'Create New HTTP Request
request = DirectCast(WebRequest.Create(webTarget), HttpWebRequest)
request.Method = "POST"
request.ContentType = "application/x-www-form-urlencoded"
Dim byteArray As Byte() = Encoding.ASCII.GetBytes(String.Format(post_data, "14075551212", "This is a test from VB.nET"))
request.ContentLength = byteArray.Length
'Set HTTP authorization header
'authUser holds the username whereas authPassword for password given by the gateway provider
Dim authInfo As String = authUser & ":" & authPassword
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo))
request.Headers("Authorization") = "Basic " & authInfo
'Send HTTP Request
Dim PostStream As Stream = request.GetRequestStream()
PostStream.Write(byteArray, 0, byteArray.Length)
response = request.GetResponse()
MessageBox.Show("Message Successfully Sent", "", MessageBoxButtons.OK, MessageBoxIcon.Information)
Catch ex As WebException
If ex.Status = WebExceptionStatus.ProtocolError Then
Dim resp As WebResponse = ex.Response
Dim sr As StreamReader = New StreamReader(resp.GetResponseStream())
MessageBox.Show(sr.ReadToEnd(), "SMS", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
Catch ex As Exception
ShowException(ex.GetType().ToString(), ex.Message)
End Try
End Sub
Once the subroutine is in place, sending a message is a single line. Pass the sender number assigned by your provider, the destination number, and the message text:
SendSMS("FromNumber", "ToNumber", "Your message body here")
Where FromNumber is the originating number assigned to you by the gateway provider, ToNumber is the recipient's number in the format your provider expects (typically E.164, such as +14075551234), and the third argument is the message body.
A few points worth understanding before plugging this into a real application:
- Form-encoded body: The payload is built as a URL-encoded query string and written to the request stream as raw bytes.
HttpUtility.UrlEncodeon the message text ensures that spaces, ampersands, and special characters in the message body do not break the parameter parsing on the gateway side. - Basic authentication: The credentials are concatenated as
username:password, Base64-encoded, and sent in theAuthorizationheader. This is the standard Basic auth scheme. Note that Basic auth over plain HTTP exposes credentials in transit; always use an HTTPS endpoint in production. - Protocol error handling: The
WebExceptioncatch block checks specifically forProtocolError, which covers HTTP 4xx and 5xx responses. Reading the response body fromex.Responsein that branch gives you the error detail the gateway returned, which is far more useful than the generic exception message alone.
HttpWebRequest is the legacy HTTP client in .NET. If you are on .NET 5 or later, even in a VB.NET project, HttpClient is the preferred replacement. It supports async/await natively, reuses connections across calls, and avoids the socket exhaustion issues that can occur when HttpWebRequest instances are created and discarded frequently.