Send text SMS to subscriber

This part of the SMS API enables a third party to send text SMSes to an authorized subscriber. This requires that the API keyholder has the authorization to send to that subscriber, which is set in the to_subscriber field.

FieldDescription
to_subscriberThe E.164 number starting with '+' of the subscriber.

It is possible to set the origin address to international numbers, short numbers or a text address. Each of these has specific restrictions based on the rights of the product to the subscriber, as this is based on a matrix of the rights and policies of the subscriber and the product, you must check for rejected messages based on it's content.

FieldContentDescription
from_address+numberAn international number in E.164 format starting with '+'.
from_addressnumberA short format (abbreviated) or network specific number in the national format. Numbers resolving to international must be entered as international.
from_addresstextA text address. Limited to printable GSM7 characters and whitespace, and must contain at least one letter. See GSM 23.034open in new window section on the default charset to see what is allowed.

All sender IDs must be pre-approved before use. You may configure sender IDs at your product's configuration page on the Developer Portalopen in new window.

Note that this is a message to the authorized subscriber. If you need to set the from_international field to a specific subscriber, you should rather use the Sending text SMS from subscriber part of the API.

Fragmentation

SMS messages have a normal limit of 160 GSM7 encoded characters, meaning messages larger than that will be fragmented. This fragmentation is handled by the API. If the encoded content is larger than the max limit for a single message we will split the message in fragments than can fit, and the handset will re-assemble them back to a single message.

Encoding

The content field as a general rule uses and supports UTF-8 fully, though as unicode support usually requires software and sometimes firmware upgrades on handsets to be shown correctly, there may be a limit to what characters will show up on the user's handset as intended.

This is a limit on both the protocols used to talk to the handsets, and to the handsets themselves. The API itself is build to support all of unicode, but thus cannot guarantee that everything will show correctly.

EncodingDescription
GSM7Default encoding used for SMS text messages. This packs for the most part 160 characters per message, or 153 on multi-fragmented message, but is limited to most common western languages.
GSM7 with National Language IdentifierExtension to GSM7 from 2012 that allows for GSM7-like packed content for Portuguese, Spanish, and the major Pakistani and Indian languages. Allows 153 characters for short messages and 146 characters per multi-fragment messages.
UCS2Unicode BMP (basic multilingual plane) characters, which uses 2 bytes per character, leaving 70 chars per fragment, or 67 for multi-fragmented. This does not support extended characters (newer emojis and CJK characters) according to the specification, but most modern handsets allows it anyway.

The API will detect and attempt to use the most efficient encoding available based on the characters in the text, though the same encoding will be used on all generated fragments.

Limitations

There are also some other restrictions to this API.

  • This API cannot send a message to the subscriber that are blocked by subscription policies or quotas.
  • This API will not send messages larger than 2000 characters. Note that unicode characters outside of the BMP plane counts as 2 characters each, and number of emoji characters and the newer CJK characters are in this group. Worst case this is 35 fragments for a single message.
  • This API does not guarantee that the message is successfully delivered.

Prerequisites

  1. An OAuth 2.0 client
  2. A client access token

Required scope

  • sms.text:send_to_subscriber is required to use the API function.

Code

TIP

You can test our APIs without authorization by targetting sandbox.api.wgtwo.com instead of api.wgtwo.com and removing any authorization from the request/code sample.

Download proto definitions
curl -sL 'https://github.com/working-group-two/wgtwoapis/blob/master/image.bin?raw=true' -o wgtwo.bin
1
export ACCESS_TOKEN="my_client_access_token"
grpcurl -protoset wgtwo.bin \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '
  {
    "content": "My text message",
    "fromAddress": "MyProduct",
    "toSubscriber": "+47xxxxxxxx"
  }
  ' \
  api.wgtwo.com:443 \
  wgtwo.sms.v1.SmsService/SendTextToSubscriber
1
2
3
4
5
6
7
8
9
10
11
12

Example result

{
  "messageId": "6a75356e-6191-11ec-b47d-7382e9b102b6",
  "status": "SEND_STATUS_OK",
  "numFragments": 1
}
1
2
3
4
5
Install dependencies

Maven

<dependency>
  <groupId>com.wgtwo.api.v1.grpc</groupId>
  <artifactId>sms</artifactId>
  <version>1.10.1</version>
</dependency>
package com.example.sms

import com.wgtwo.api.v1.sms.SmsProto.SendTextToSubscriberRequest
import com.wgtwo.api.v1.sms.SmsServiceGrpc
import com.wgtwo.auth.BearerTokenCallCredentials
import io.grpc.ManagedChannelBuilder

/** Use the sandbox environment for testing without authentication */
private val environment = Environment.SANDBOX

private val endpoint = when (environment) {
    Environment.SANDBOX -> "sandbox.api.wgtwo.com"
    Environment.PRODUCTION -> "api.wgtwo.com"
}
private val channel = ManagedChannelBuilder.forAddress(endpoint, 443).build()
private val stub = SmsServiceGrpc.newBlockingStub(channel).apply {
    /**
     * If you are not using the sandbox, you need to add credentials.
     * The BearerTokenCallCredentials class can be found in our auth library.
     */
    if (environment == Environment.PRODUCTION) {
        this.withCallCredentials(BearerTokenCallCredentials { "MY_CLIENT_ACCESS_TOKEN" })
    }
}

fun main(vararg args: String) {
    require(args.size == 3) { "This program requires 3 arguments: from-number to-number content" }

    val request = SendTextToSubscriberRequest.newBuilder().apply {
        fromAddress = args[0]
        toSubscriber = args[1]
        content = args[2]
    }.build()
    println("Request:\n$request")
    val response = stub.sendTextToSubscriber(request)
    println("Response:\n$response")

    channel.shutdownNow()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

Example result

message_id: "6a75356e-6191-11ec-b47d-7382e9b102b6"
status: SEND_STATUS_OK
num_fragments: 1
1
2
3

Read more