Rules
SMS Type
SendCloud SMS platform currently supports verification code, business notice and marketing messages.
Verification code messages:registration password, password modification, authentication, etc.
Business notice messages:notice triggered by user behaviors, such as order notice, reply notice, etc.
Marketing messages: messages or notices bulky sent to users.
Accessing Method
Sendcloud currently provides WEBAPI for users to access SMS platform. Developers can call SendCloud SMS service via provided HTTP interfaces.
To use SMS API, you need to create:
- SMS_USER
- SMS_KEY
- SMS Template
- Signature
SMS_USER and SMS_KEY
SMS_USER is the account used to call interfaces to send messages
Users can create SMS_USER in 【SMS and Voice SMS】-【settings】-【authorization】
and SendCloud will generates a corresponding SMS_KEY.Every user is only allowed for one SMS_USER.
SMS Template
Users are required to edit SMS content and submit it for verification in front page before sending messages. After verification, users can call templates to send SMS with template ID.
Variable Replacement
「variable」 is allowed in messages.
Format of variable:%
at head and tail, between which is the custom variable. Example:
欢迎使用爱发信. 您的手机验证码是: %code%. # code是变量
Usages of variable:
- Used as placeholder in SMS template
- Set variable value in SMS API
- SendCloud will replace corresponding variable value in the message on the basis of request parameter
- Variable value cannot be longer than 32 characters, and must not contain HTTP link
Naming rules of variable:
- Variable name can only include letters (upper-case and lower-case), numbers, “_” (underline) , “-“ (strikethrough) or any combination.
- Variable must start with letters (upper-case and lower-case), numbers, “_” (underline) or “-“ (strikethrough)
- Variable name cannot be longer than 32 characters
Signature
Due to the particularity of SMS and the censorship of ISP institutions, a signature that shows the identity of sender is required in messages. You can add signature when editing SMS templates, and set signature position (end of the message only).
Note:
SMS template must contain 「signature」 or it will fail the verification.Each user is allowed to have one signature.
SMS Recording
SMS Recording is an information verification by mobile operators, which impacts SMS delivery rate.
After calling SMS interface, users can apply for SMS recording in 【SMS and Voice SMS】-【Settings】-【SMS Recording】. Steps are as below:
- Download letter of commitment and print it out;
- Read letter of commitment carefully and make sure it’s signed by the responsible person and stamped with the company’s seal;
- Convert it to digital copy in JPG or PDF format by photographing or scanning;
- Upload the digital copy for verification. The result comes out within one day.
Intercept List
To reduce invalid messages, SendCloud will intercept some numbers according to the result from mobile operators.
All numbers in sending failed
will be added to intercept list. The records are as below:
- Phone numbers: intercepted numbers
- Intercepting time: messages after this time will be intercepted
- Expired time: messages will be sent normally after this time
- Reason: result from mobile operators
Different failure reason lead to different intercepting time and intercepting scope. See below:
Return Code | Failure Description | intercepting time | Global/local intercept | whether can be removed |
---|---|---|---|---|
500 | sending failure, number nonexistent | 30 days | global intercept | yes |
510 | sending failure, number out of service | 1 hour | global intercept | yes |
520 | sending failure, number in blacklist | 1 hour | global intercept | yes |
530 | sending failure, busy line | 0 s | yes | |
540 | sending failure, no answer | 0 s | yes | |
550 | sending failure, template content intercepted | 1 hour | global intercept | yes |
560 | sending failure, mobile terminal error | 1 hour | global intercept | yes |
570 | sending failure, mobile not in service | 1 hour | global intercept | yes |
580 | sending failure, mobile powered off | 0 s | yes | |
590 | sending failure, other reasons | 0 s | yes |
global intercept: this intercept record applies to all SendCloud users
global intercept: this intercept record only applies to originated users
Users can remove numbers originated from themselves
.To remove other numbers
in the intercept list, you need to contact customer service.
API Verification Mechanism
Digital signature is used to effectively avoid password leakage during the SMS transmission. Digital signature is proved as a secure verification method.
When calling API, users transmit digital signature to the server and do not need to transmit password (SMS_KEY) as a parameter. The server will verify the digital signature.
Method of generating digital signature:
1. Alphabeticlly arrange the paramters;smsKey and signature are not included
2. Link all parameters by means of 'key=value' + '&' + 'key=value' to generate string param_str
3. Generate string sign_str by means of SMS_KEY + '&' + param_str + '&' + SMS_KEY
4. Calculate MD5(32 characters,not case sensitive) or sha256 to get signature
Tips:
1. Do not use `urlencode` when generating signature;`urlencode` is required when calling API
2. '&' is the connector in code; `+` is used for document display
Code example (python) is as below:
import hashlib
SMS_USER = 'testuser'
SMS_KEY = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
param = {
'smsUser': SMS_USER,
'templateId' : 1,
'phone' : 18888888888,
'vars' : {},
}
param_keys = list(param.keys())
param_keys.sort()
param_str = ''
for key in param_keys:
param_str += key + '=' + str(param[key]) + '&'
param_str = param_str[:-1]
sign_str = SMS_KEY + '&' + param_str + '&' + SMS_KEY
signature = hashlib.sha256(sign_str).hexdigest()
Tip: all APIs support HTTP
Timestamp (To be classy)
Users can add timestamp to every API request. If difference between timestamp and sever time is more than 60 seconds, the request will be rejected.
Users obtain SendCloud sever timestamp via API, which is not the local time.
“timestamp” should be included in signature for digital signature creation.
SMSHook
SMSHook mechanism
When users submit SMS or voice request to SendCloud, 「request result」 will be simultaneously returned to users; SMS or voice 「sending result」 and 「results of other event」 will be asynchronously returned to users via SMSHook.
- SendCloud provides several events for users to choose
- When an event occurs, the URL set by SendCloud will be triggered to send data (POST)
- Users parse the event and data for follow-up processing after receiving the data
Supported events are as below:
Events | Triggering Conditions |
---|---|
request (request) | request was successful |
deliver (deliver) | delivered |
process failure(workererror) | processing failed |
delivery failure(delivererror) | delivering failed |
click link(click) | User clicks the link |
reply(reply) | reply (SMS only) |
SMS uplink(sms_mo) | Users actively submit SMS to the interface |
Template approval(templateVerify) | Approval result message of SMS template |
Usage Method:
- Users write HTTP service to process events, parse data and release URL
- Choose interested events in
【SMS and Voice SMS】-【Settings】-【SMSHook】
and configure URL
Note: SendCloud will test users’ URL to ensure the HTTP service responds to get | post request, and the returned HTTP status code is 200
Signature Verification
To ensure that the message is sent from SendCloud, you can choose to verify the source of the POST data. (You can also parse POST data without authentication).
Authentication method is as below:
- Acquire
APP KEY
in【SMS and Voice SMS】- 【Delivery Settings】-【SMSHook】
. - Parse
token
,timestamp
andsignature
in POST data. - Generate signature with
APP KEY
,token
andtimestamp
; check it withsignature
in POST data (signature algorithm: SHA256)
Python code example
import hashlib, hmac
def verify(appkey, token, timestamp, signature):
return signature == hmac.new(
key=appkey,
msg='{}{}'.format(timestamp, token),
digestmod=hashlib.sha256).hexdigest()
Java code example (dependent apache codec)
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;
public boolean verify(String appkey, String token, long timestamp,
String signature) throws NoSuchAlgorithmException, InvalidKeyException {
Mac sha256HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(appkey.getBytes(),"HmacSHA256");
sha256HMAC.init(secretKey);
StringBuffer buf = new StringBuffer();
buf.append(timestamp).append(token);
String signatureCal = new String(Hex.encodeHex(sha256HMAC.doFinal(buf
.toString().getBytes())));
return signatureCal.equals(signature);
}
php code example
function verify($appkey,$token,$timestamp,$signature){
$hash="sha256";
$result=hash_hmac($hash,$timestamp.$token,$appkey);
return strcmp($result,$signature)==0?1:0;
}
Event Description
SMSHook now supports request, deliver, process failure, send failure and reply.
Request ( request )
Parameter Description
parameter | type | description |
---|---|---|
event | string | event type: ”request” |
eventType | int | event type code:1 |
message | string | SMS content |
smsUser | string | smsUser |
smsIds | list | SMS (Voice SMS) IDs |
templateId | int | template ID |
phones | list | phone numbers |
timestamp | long | timestamp |
token | string | random string of 50 characters |
signature | string | signature string |
userId | int | user ID |
labelId | int | reserved, temporarily out of use |
tag | string | User defined tag |
msgCount | int | Number of SMS |
msgType | int | "0"SMS, "1"MMS, "2"International SMS, "3"International Voice |
smsType | int | "0"Verification Code, "1"Notice, "2"Marketing |
POST data example
{
"msgType":0,
"signature":"1ff237043487aeb4dc1b21c22b5ead9e4df94a31a3afa0ad53238eb38c2cbeea",
"phones":"[\"13888888888\"]",
"eventType":1,
"templateId":29999,
"message":"request",
"userId":19999,
"smsUser":"App",
"smsIds":"[\"1652150994014_9373_14466_36735_99drnc$13888888888\"]",
"token":"VDymF6ihuJkKZjHiJZkLKGmY6q9qAQ2WGopLh7mBsDeAO6GKV5",
"labelId":0,
"smsType":0,
"tag":0,
"event":"request",
"timestamp":1652150994087
}
Deliver ( deliver )
Parameter Description
parameter | type | description |
---|---|---|
event | string | event type: ”deliver” |
eventType | int | event type code:2 |
message | string | SMS content |
smsUser | string | smsUser |
smsId | string | SMS (Voice SMS) IDs |
templateId | int | template ID |
phone | string | phone numbers |
timestamp | long | timestamp |
token | string | random string of 50 characters |
signature | string | signature string |
userId | int | user ID |
labelId | int | reserved, temporarily out of use |
tag | string | User defined tag |
msgCount | int | Number of SMS |
msgType | int | "0"SMS, "1"MMS, "2"International SMS, "3"International Voice |
smsType | int | "0"Verification Code, "1"Notice, "2"Marketing |
outboundTime | string | Channel time |
receiptTime | string | Receipt time |
POST data example
{
"outboundTime":"2022-05-10 01:29:31",
"msgType":0,
"signature":"9ca96fa072bfa048969aa0cb7bf7baf64100234640a1b9793cca1a419afb9cb8",
"eventType":2,
"templateId":29999,
"message":"Successfully delivered",
"userId":19999,
"smsUser":"APP",
"token":"4mRG9lGhVb3jZhOMnksFPBtX1OLDMNZMfXTFHkFd9eybfdRiHM",
"smsId":"1652117371408_19999_376_4631_qrwnpq$13888888888",
"receiptTime":"2022-05-10 01:29:50",
"labelId":0,
"phone":"13888888888",
"msgCount":1,
"smsType":1,
"tag":0,
"event":"deliver",
"timestamp":1652117390000
}
Process failure ( workererror)
Parameter Description
parameter | type | description |
---|---|---|
event | string | event type:"workererror" |
eventType | int | event type code:4 |
message | string | SMS content |
encodeMessage | string | SMS content of base64 encoding |
statusCode | int | error code |
smsUser | string | smsUser |
smsId | string | SMS (Voice SMS) IDs |
templateId | int | template ID |
phone | string | phone numbers |
timestamp | long | timestamp |
token | string | random string of 50 characters |
signature | string | signature string |
userId | int | user ID |
labelId | int | reserved, temporarily out of use |
tag | string | User defined tag |
msgCount | int | Number of SMS |
msgType | int | "0"SMS, "1"MMS, "2"International SMS, "3"International Voice |
smsType | int | "0"Verification Code, "1"Notice, "2"Marketing |
outboundTime | string | Channel time |
POST data example
{
"outboundTime":"2022-05-10 00:00:54",
"msgType":0,
"signature":"8a3a030169decf0134010b8d7443cfbbf16b08a6aee524291706dacfb127be95",
"eventType":4,
"templateId":-3,
"message":"smsworker:address in unsubscribe list(取消订阅)",
"userId":19999,
"smsUser":"APP",
"token":"sGfR3yMheseXBxkPt3NnIuDQK5aYdzbfyUO8i0oz6IJI07pNHj",
"smsId":"1652112054796_19999_167_-3_ty8pqn$13888888888",
"labelId":0,
"encodeMessage":"c21zd29ya2VyOmFkZHJlc3MgaW4gdW5zdWJzY3JpYmUgbGlzdCjlj5bmtojorqLpmIUp",
"phone":"13888888888",
"msgCount":1,
"smsType":1,
"tag":0,
"event":"workererror",
"timestamp":1652112054846,
"statusCode":430
}
Send failure ( delivererror)
Parameter Description
parameter | type | description |
---|---|---|
event | string | event type:"delivererror" |
eventType | int | event type code:5 |
message | string | SMS content |
encodeMessage | string | SMS content of base64 encoding |
statusCode | int | error code |
smsUser | string | smsUser |
smsId | string | SMS (Voice SMS) IDs |
templateId | int | template ID |
phone | string | phone numbers |
timestamp | long | timestamp |
token | string | random string of 50 characters |
signature | string | signature string |
userId | int | user ID |
labelId | int | reserved, temporarily out of use |
tag | string | User defined tag |
msgCount | int | Number of SMS |
msgType | int | "0"SMS, "1"MMS, "2"International SMS, "3"International Voice |
smsType | int | "0"Verification Code, "1"Notice, "2"Marketing |
outboundTime | string | Channel time |
receiptTime | string | Receipt time |
POST data example
{
"outboundTime":"2022-05-10 09:31:12",
"msgType":0,
"signature":"785370449703a5dfca4cb773a5a266f6be1db8bdbe713b8ce74ca572f9788a7a",
"eventType":5,
"templateId":29999,
"message":"REJECTD(其他)",
"userId":19999,
"smsUser":"APP",
"token":"MTha34FTrBRBmJXdZK4qVCqRxh8N4IlAJlM11sd1FSfCk9jmo3",
"smsId":"1652146271665_19999_8755_3883_37059m$13888888888",
"receiptTime":"2022-05-10 09:31:17",
"labelId":0,
"encodeMessage":"UkVKRUNURCjlhbbku5Yp",
"msgCount":1,
"smsType":0,
"tag":0,
"event":"delivererror",
"timestamp":1652146277000,
"statusCode":590
}
Click url ( click)
Parameter Description
parameter | type | description |
---|---|---|
event | string | event type:"click" |
eventType | int | event type code:9 |
clickUrl | string | User clicks the link |
message | string | SMS content |
smsUser | string | smsUser |
smsId | string | SMS (Voice SMS) IDs |
templateId | int | template ID |
phone | string | phone numbers |
timestamp | long | timestamp |
token | string | random string of 50 characters |
signature | string | signature string |
userId | int | user ID |
labelId | int | reserved, temporarily out of use |
tag | string | User defined tag |
msgType | int | "0"SMS, "1"MMS, "2"International SMS, "3"International Voice |
smsType | int | "0"Verification Code, "1"Notice, "2"Marketing |
ip | string | ip |
deviceName | tring | device name |
deviceType | int | device type |
oSName | string | OS Name |
oSVer | string | OS version |
explorerName | string | explorer name |
explorerVer | string | explorer version |
POST data example
{ "clickUrl": "https://ifaxin.com", "deviceType": "1", "msgType": "0", "signature": "ee7a01678cdc69a53074a0f5516c93541c7d0bd60758d5344ece26b8347002e8", "ip": "124.127.61.82", "eventType": "10", "templateId": "868058", "message": "click sms", "userId": "15", "smsUser": "sms_ss", "deviceName": "Other", "token": "uTuoR0IzT1OSQqP1ykjG5QP1cQF9rdomhLkGkse3FbZwhE7UF7", "oSName": "Windows 7", "explorerName": "Chrome", "smsId": "1668413622360_15_9_868058_uny9w1$13437150000", "explorerVer": "86.0.4240", "labelId": "0", "tag": "0", "phone": "13437150000", "smsType": "1", "event": "click", "oSVer": "", "timestamp": "1668413648109" }
Reply (reply)
parameter | type | description |
---|---|---|
event | string | event type:"reply" |
eventType | int | event type code:6 |
smsUser | string | smsUser |
templateId | int | template ID |
phone | string | phone numbers |
timestamp | long | timestamp |
token | string | random string of 50 characters |
signature | string | signature string |
userId | int | user ID |
labelId | int | reserved, temporarily out of use |
replyContent | string | reply content |
encodeReplyContent | string | reply content of base64 encoding |
replyTime | Datetime | reply time |
tag | string | User defined tag |
msgCount | int | Number of SMS |
msgType | int | "0"SMS, "1"MMS, "2"International SMS, "3"International Voice |
smsType | int | "0"Verification Code, "1"Notice, "2"Marketing |
POST data example
{
"msgType":0,
"signature":"3a9ab5dd4ca5ee56dee8c8998f11a1ec33ce5bcd720987aff86b6608fc967a3d",
"eventType":6,
"templateId":29999,
"userId":19999,
"smsUser":"APP",
"encodeReplyContent":"5a6i5pyN55S16K+d5piv5ZOq5Liq5Y+356CB",
"token":"MTY8WxQIUUWyKjke1MTWpPu88mxxmHINTsT7x2DwJZQq2VynNl",
"replyTime":"2022-05-10 08:49:14",
"labelId":0,
"phone":"13888888888",
"smsType":0,
"replyContent":"客服电话是哪个号码",
"tag":0,
"event":"reply",
"timestamp":1652143756604
}
SMS uplink (sms_mo)
parameter | type | |
---|---|---|
event | string | event type:"reply" |
eventType | int | event type code:7 |
smsUser | string | smsUser |
templateId | int | template ID |
phone | string | phone numbers |
timestamp | long | timestamp |
token | string | random string of 50 characters |
signature | string | signature string |
userId | int | user ID |
labelId | int | reserved, temporarily out of use |
replyContent | string | sms_mo reply content |
encodeReplyContent | string | base64编码的回复内容 |
replyTime | Datetime | sms_mo reply time |
tag | string | User defined tag |
msgCount | int | Number of SMS |
msgType | int | "0"SMS, "1"MMS, "2"International SMS, "3"International Voice |
smsType | int | "0"Verification Code, "1"Notice, "2"Marketing |
POST data example
{
"msgType":0,
"token":"0IwiTzCRJFwlS40cwQRPXP0j61xg3B9RNLFu5WpC9jD0CruWdT",
"timestamp":"1566293197107",
"labelId": 0,
"phone":"13888888888",
"replyContent":"test_mo",
"encodeReplyContent":"dGVzdF9tbw==",
"replyTime":"2019-08-16 16:16:16",
"userId":19999,
"templateId":-1,
"smsUser":"smsuser",
"event":"sms_mo",
"signature":"da7339b7ddbd1228c2bcd8abdc80e28ad37fba3dd5c73dfb18e6ca91e6ae7715",
"eventType": 7,
"tag":0,
"smsType":0
}
Template approval (templateVerify)
parameter | type | description |
---|---|---|
event | string | event type:"templateVerify" |
eventType | int | event type code:8 |
templateId | int | template ID |
name | string | 模板名称 |
timestamp | long | timestamp |
token | string | random string of 50 characters |
signature | string | signature string |
userId | int | user ID |
verfiyResult | int | 审核结果:0审核中,1通过,-1不通过 |
verfiyComment | string | 审核意见.审核不通过时有verfiyComment |
msgType | int | "0"SMS, "1"MMS, "2"International SMS, "3"International Voice |
smsType | int | "0"Verification Code, "1"Notice, "2"Marketing |
POST data example
{
"msgType":0,
"signature":"b80266d81f527c1ce870ba36c4c9e79fd9725c5a7c943577a25d8116aa67c927",
"verfiyResult":1,
"name":"感谢莅临上海车展展台",
"smsType":1,
"eventType":8,
"templateId":6255,
"event":"templateVerify",
"userId":102,
"token":"M1dgqmmOsM3BC9dCqBsMjtDh6I5jYwXngPEtcVV9v8XoplF1VQ",
"timestamp":1646628597226
}