logo
logo
请输入关键词搜索产品或者文档
中国

中国站

创蓝云智

国际站

Innopaas

短信发送

更新时间:2026-10-21 11:11:42

1.注意事项

  1. 号码格式:国家码+手机号码,不带+号和00前缀。例如中国大陆号码:8617321342252。

  2. 发送至中国大陆:国际接口默认关闭国内发送权限,如需发送请联系对应商务申请开通。开通后请注意:

    • 号码格式为"86+手机号",如8613800001111
    • 短信内容必须以【签名】开头,签名为公司或品牌名称,如【创蓝云智】
    • 短信内容需提前报备,审核通过后方可发送
  3. 发送至国外:

    • 无需报备,签名不限制
    • 营销短信建议使用英文或当地语言
    • 如需使用中文发送,请联系商务确认目标国家运营商是否支持中文
  4. 计费规则:

    • 国际短信不支持 emoji 表情

    • 短信中含非英文字符按中文计费

    • 编辑器中空格都会以"."表示,如出现不带"."的空格则说明有隐藏代码,会导致 1 条短信算成 2 条的风险请留意

    • 超链接地址请写在短信内容中,便于核实,部分安卓系统存在超链接识别问题,需在超链接前后添加空格

  5. 异常排查:如遇短信收到慢或收不到,请联系对应商务或客服,常见原因包括号码格式错误、内容触发审核、号码在黑名单中。

2.接口加签方式

  1. 将请求头参数名 nonce 及所有请求体参数名(key)以 ASCII 码表顺序升序排列;
  2. 排序后把参数值非空的参数名(key)参数值(value)依次进行字符串拼接,拼接处不包含其他字符;
  3. 拼接成包含 kv 的长串后,在该长串的尾部拼接账号的 password,得到签名字符串的组装;
  4. 最后对签名字符串,使用 MD5 算法加密后,得到 MD5 加密密文后转为小写,即为请求头 sign 值

拼接示例:

参数:account=I6000000, mobile=8615800000000, msg=【253】test, nonce=1653043349000, uid=123456
拼接结果:accountI6000000mobile8615800000000msg【253】testnonce1653043349000uid123456 + password
sign值:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

2.1代码示例

package com.angi;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.DigestUtils;

import java.util.Map;
import java.util.TreeMap;

/**
 * 参数进行加签验签
 */
public class SignUtil {
    private static final String SIGN = "sign";

    /**
     * 发送加签
     */
    public static String sendSign(String password, TreeMap<String, String> paramMap) {
        paramMap.remove(SIGN);
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> entry : paramMap.entrySet()) {
            if (StringUtils.isNotBlank(entry.getValue())) {
                sb.append(entry.getKey());
                sb.append(entry.getValue());
            }
        }
        return DigestUtils.md5DigestAsHex((sb.toString() + password).getBytes()).toLowerCase();
    }

    /**
     * 发送验签
     */
    public static boolean verifySendSign(String password, TreeMap<String, String> paramMap) {
        String sign = paramMap.remove(SIGN);
        String computed = sendSign(password, paramMap);
        return StringUtils.equals(sign, computed);
    }

    public static void main(String[] args) {
        /*发送加签验签*/
        String password = "4Z7bMS1eLI6895";
        TreeMap<String, String> paramMap = new TreeMap<>();
        paramMap.put("nonce", "222222");
        paramMap.put("account", "IM6742671");
        paramMap.put("mobile", "8618916198813");
        paramMap.put("msg", "test 666661 ");
        System.out.println(JSONObject.toJSONString(paramMap));
        String sign = sendSign(password, paramMap);
        System.out.println(sign);

        TreeMap<String, String> newParamMap = new TreeMap<>(paramMap);
        newParamMap.put(SIGN, sign);

        boolean validate = verifySendSign(password, newParamMap);
        System.out.println(validate);
    }
}

2.2DEMO文件

加密DEMO点此获取

3.发送短信接口

3.1接入准备

查询API账号信息

查询账号归属节点

配置IP白名单

配置数据推送URL

3.2协议说明

名称说明
协议HTTP POST
编码格式UTF8
Content-Typeapplication/json
URL(新加坡节点)https://sg-intapi.tig253.com/send/sms
URL(上海节点)https://intapi.tig253.com/send/sms

请根据账号归属节点请求对应URL,否则可能会导致请求失败

3.3请求头

参数名类型是否必填示例说明
signstring是54aefa13a6e86c119db54a6d07e8721b签名,请参考加签方式生成签名
noncestring是1787279054149毫秒级时间戳

3.4请求体

参数名类型是否必填示例说明
accountstring是I6000000API账号,以大写字母I开头,登录云通讯控制台获取
mobilestring是8615800000000手机号码,格式为"国家码+手机号",不带+和00前缀。例如中国:8615800000000,美国:12025550100。批量发送时多个号码用英文逗号隔开,如8615800000000,8615800000001。长度5-20位
msgstring是【253】Your verification code is: 2530短信内容,长度不超过3000个字符。发送至中国大陆时必须以【签名】开头且内容需提前报备
senderIdstring否ChuangLan收件人手机上显示的发件人名称。中国大陆不支持自定义;海外支持自定义,需提前联系创蓝商务申请注册
uidstring否2026082110001客户自定义批次号,64个字符以内
callBackUrlstring否https://your-domain.com/callback状态报告回调地址,需以http://或https://开头。不传则使用控制台配置的地址,请勿传入空格
tdFlagint否0退订功能标识:1=开启,0或null=关闭。

请求示例

// 请求头
sign: 54aefa13a6e86c119db54a6d07e8721b
nonce: 1787279054149
Content-Type: application/json

// 请求体
{
    "account": "I6000000",
    "mobile": "8615800000000",
    "msg": "【253】Your verification code is: 2530",
    "senderId":"ChuangLan",
    "uid": "2026082110001",
    "callBackUrl":"https://your-domain.com/callback"  
}

3.5响应体

名称类型示例说明
codestring0状态码: 0-成功,非 0 标识失败
messagestring提交成功状态码说明
datastringnull消息体

响应示例-成功

单条发送成功:

{
  "code": "0",
  "message": "提交成功",
  "data": {
    "messageId": "392752647001866752"
  }
}

批量发送成功(含失败号码):

{
  "code": "0",
  "message": null,
  "data": {
    "messageId": "B_I1266966_2608211442481190200032100001",
    "errorPhone": [
      "111111111"
    ]
  }
}

响应示例-失败

{
  "code": "108",
  "message": "手机号码格式错误",
  "data": null
}

多语言调用示例

Java

package com.chuanglan.intsms.demo;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.DigestUtils;

import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;

/**
 * ChuanglanIntsmsDemo
 *
 * @author xuzhilu
 * @createdAt 2026/6/30 17:12
 * @description 创蓝国际短信发送接口代码示例
 */
public class ChuanglanIntsmsDemo {

    private static final String API_URL = "https://sg-intapi.tig253.com/send/sms";

    private final OkHttpClient httpClient = new OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .readTimeout(10, TimeUnit.SECONDS)
            .writeTimeout(10, TimeUnit.SECONDS)
            .build();

    public static void main(String[] args) throws IOException {
        new ChuanglanIntsmsDemo().sendSms();
    }

    public void sendSms() throws IOException {
        //替换为API账号的密码
        String password = "You account password";

        SmsSendRequest smsRequest = new SmsSendRequest();
        smsRequest.setAccount("I123456");
        smsRequest.setMobile("6289520123456");
        smsRequest.setMsg("这是一条测试短信");
        smsRequest.setUid("112233445566778899");

        String nonce = String.valueOf(System.currentTimeMillis());
        String sign = generateSign(password, smsRequest, nonce);

        String jsonBody = JSON.toJSONString(smsRequest);
        RequestBody body = RequestBody.create(
                MediaType.parse("application/json; charset=utf-8"),
                jsonBody
        );

        Request request = new Request.Builder()
                .url(API_URL)
                .header("Content-Type", "application/json")
                .header("nonce", nonce)
                .header("sign", sign)
                .post(body)
                .build();

        try (Response response = httpClient.newCall(request).execute()) {
            String result = response.body() != null ? response.body().string() : "";
            System.out.println("响应结果: " + result);

            JSONObject rtn = JSON.parseObject(result);
            String code = rtn.getString("code");
            if ("0".equals(code)) {
                System.out.println("提交成功");
                String messageId = rtn.getJSONObject("data").getString("messageId");
                System.out.println("messageId=" + messageId);
            } else {
                String.format("提交失败: code=%s, message=%s", code, rtn.getString("message"));
            }
        }
    }

    /**
     * 生成签名
     *
     * @param password   API账号密码
     * @param smsRequest 发送请求参数
     * @param nonce      一般为时间戳
     * @return
     */
    private String generateSign(String password, SmsSendRequest smsRequest, String nonce) {
        //使用TreeMap排序
        TreeMap<String, String> paramMap = JSON.parseObject(
                JSON.toJSONString(smsRequest),
                new TypeReference<TreeMap<String, String>>() {
                }
        );
        paramMap.put("nonce", nonce);

        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> entry : paramMap.entrySet()) {
            if (StringUtils.isNotBlank(entry.getValue())) {
                sb.append(entry.getKey());
                sb.append(entry.getValue());
            }
        }
        //追加API账号密码
        String signContent = sb.append(password).toString();
        return DigestUtils.md5DigestAsHex(signContent.getBytes()).toLowerCase();
    }

    /**
     * 国际短信发送请求实体
     */
    public static class SmsSendRequest {
        // API账号
        private String account;

        // 短信接收号码,带区号,如:6289520123456
        private String mobile;

        //短信内容
        private String msg;

        //批次号
        private String uid;

        public String getAccount() {
            return account;
        }

        public void setAccount(String account) {
            this.account = account;
        }

        public String getMobile() {
            return mobile;
        }

        public void setMobile(String mobile) {
            this.mobile = mobile;
        }

        public String getMsg() {
            return msg;
        }

        public void setMsg(String msg) {
            this.msg = msg;
        }

        public String getUid() {
            return uid;
        }

        public void setUid(String uid) {
            this.uid = uid;
        }
    }


}

Python

import hashlib
import json
import time
import requests


class SmsSendRequest:
    """国际短信发送请求实体"""

    def __init__(self, account=None, mobile=None, msg=None, uid=None):
        # API账号
        self.account = account
        # 短信接收号码,带区号,如:6289520123456
        self.mobile = mobile
        # 短信内容
        self.msg = msg
        # 批次号
        self.uid = uid

    def to_dict(self):
        return {
            "account": self.account,
            "mobile": self.mobile,
            "msg": self.msg,
            "uid": self.uid,
        }


class ChuanglanIntsmsDemo:
    """
    创蓝国际短信发送接口代码示例
    """

    API_URL = "https://sg-intapi.tig253.com/send/sms"

    def __init__(self):
        self.timeout = 10  # 超时时间(秒)

    def send_sms(self):
        # 替换为API账号的密码
        password = "You account password"

        sms_request = SmsSendRequest(
            account="I123456",
            mobile="6289520123456",
            msg="这是一条测试短信",
            uid="112233445566778899",
        )

        nonce = str(int(time.time() * 1000))
        sign = self._generate_sign(password, sms_request, nonce)

        json_body = json.dumps(sms_request.to_dict(), ensure_ascii=False)
        headers = {
            "Content-Type": "application/json; charset=utf-8",
            "nonce": nonce,
            "sign": sign,
        }

        response = requests.post(
            self.API_URL,
            data=json_body,
            headers=headers,
            timeout=self.timeout,
        )

        result = response.text
        print(f"响应结果: {result}")

        rtn = json.loads(result)
        code = rtn.get("code")
        if code == "0":
            print("提交成功")
            message_id = rtn.get("data", {}).get("messageId")
            print(f"messageId={message_id}")
        else:
            print(f"提交失败: code={code}, message={rtn.get('message')}")

    def _generate_sign(self, password, sms_request, nonce):
        """
        生成签名

        :param password: API账号密码
        :param sms_request: 发送请求参数
        :param nonce: 一般为时间戳
        :return: MD5签名字符串
        """
        # 按key字母排序(等价于Java的TreeMap)
        param_dict = sms_request.to_dict()
        # nonce 加入参数表一起排序
        param_dict["nonce"] = nonce
        sorted_keys = sorted(param_dict.keys())

        sb = []
        for key in sorted_keys:
            value = param_dict[key]
            if value is not None and str(value).strip() != "":
                sb.append(key)
                sb.append(str(value))

        # 追加API账号密码
        sign_content = "".join(sb) + password
        return hashlib.md5(sign_content.encode("utf-8")).hexdigest().lower()


if __name__ == "__main__":
    ChuanglanIntsmsDemo().send_sms()

PHP

<?php

/**
 * ChuanglanIntsmsDemo
 *
 * @author xuzhilu
 * @createdAt 2026/6/30 17:12
 * @description 创蓝国际短信发送接口代码示例
 */
class ChuanglanIntsmsDemo
{
    const API_URL = 'https://sg-intapi.tig253.com/send/sms';

    private $timeout = 10; // 超时时间(秒)

    public function sendSms()
    {
        // 替换为API账号的密码
        $password = 'You account password';

        $smsRequest = new SmsSendRequest();
        $smsRequest->account = 'I123456';
        $smsRequest->mobile  = '6289520123456';
        $smsRequest->msg     = '这是一条测试短信';
        $smsRequest->uid     = '112233445566778899';

        $nonce = strval(round(microtime(true) * 1000));
        $sign  = $this->generateSign($password, $smsRequest, $nonce);

        $jsonBody = json_encode($smsRequest->toArray(), JSON_UNESCAPED_UNICODE);
        $headers  = [
            'Content-Type: application/json; charset=utf-8',
            'nonce: ' . $nonce,
            'sign: ' . $sign,
        ];

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, self::API_URL);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonBody);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->timeout);

        $result = curl_exec($ch);
        curl_close($ch);

        echo '响应结果: ' . $result . PHP_EOL;

        $rtn  = json_decode($result, true);
        $code = $rtn['code'] ?? '';
        if ($code === '0') {
            echo '提交成功' . PHP_EOL;
            $messageId = $rtn['data']['messageId'] ?? '';
            echo 'messageId=' . $messageId . PHP_EOL;
        } else {
            $message = $rtn['message'] ?? '';
            echo "提交失败: code={$code}, message={$message}" . PHP_EOL;
        }
    }

    /**
     * 生成签名
     *
     * @param string         $password   API账号密码
     * @param SmsSendRequest $smsRequest 发送请求参数
     * @param string         $nonce      一般为时间戳
     * @return string MD5签名字符串
     */
    private function generateSign($password, $smsRequest, $nonce)
    {
        // 按key字母排序(等价于Java的TreeMap)
        $paramMap = $smsRequest->toArray();
        // nonce 加入参数表一起排序
        $paramMap['nonce'] = $nonce;
        ksort($paramMap);

        $sb = '';
        foreach ($paramMap as $key => $value) {
            if ($value !== null && trim(strval($value)) !== '') {
                $sb .= $key;
                $sb .= $value;
            }
        }
        // 追加API账号密码
        $signContent = $sb . $password;
        return strtolower(md5($signContent));
    }
}

/**
 * 国际短信发送请求实体
 */
class SmsSendRequest
{
    // API账号
    public $account;

    // 短信接收号码,带区号,如:6289520123456
    public $mobile;

    // 短信内容
    public $msg;

    // 批次号
    public $uid;

    public function toArray()
    {
        return [
            'account' => $this->account,
            'mobile'  => $this->mobile,
            'msg'     => $this->msg,
            'uid'     => $this->uid,
        ];
    }
}

// 入口
(new ChuanglanIntsmsDemo())->sendSms();

Node.js

const crypto = require('crypto');
const https = require('https');

/**
 * 国际短信发送请求实体
 */
class SmsSendRequest {
    constructor({ account, mobile, msg, uid } = {}) {
        // API账号
        this.account = account;
        // 短信接收号码,带区号,如:6289520123456
        this.mobile = mobile;
        // 短信内容
        this.msg = msg;
        // 批次号
        this.uid = uid;
    }

    toDict() {
        return {
            account: this.account,
            mobile: this.mobile,
            msg: this.msg,
            uid: this.uid,
        };
    }
}

/**
 * 创蓝国际短信发送接口代码示例
 */
class ChuanglanIntsmsDemo {
    static API_URL = 'https://sg-intapi.tig253.com/send/sms';

    constructor() {
        this.timeout = 10000; // 超时时间(毫秒)
    }

    static main() {
        new ChuanglanIntsmsDemo().sendSms();
    }

    sendSms() {
        // 替换为API账号的密码
        const password = 'You account password';

        const smsRequest = new SmsSendRequest({
            account: 'I123456',
            mobile: '6289520123456',
            msg: '这是一条测试短信',
            uid: '112233445566778899',
        });

        const nonce = Date.now().toString();
        const sign = this._generateSign(password, smsRequest, nonce);

        const jsonBody = JSON.stringify(smsRequest.toDict());
        const url = new URL(ChuanglanIntsmsDemo.API_URL);

        const options = {
            hostname: url.hostname,
            path: url.pathname,
            method: 'POST',
            headers: {
                'Content-Type': 'application/json; charset=utf-8',
                'nonce': nonce,
                'sign': sign,
                'Content-Length': Buffer.byteLength(jsonBody),
            },
            timeout: this.timeout,
        };

        const req = https.request(options, (res) => {
            let result = '';
            res.setEncoding('utf-8');
            res.on('data', (chunk) => { result += chunk; });
            res.on('end', () => {
                console.log('响应结果: ' + result);

                const rtn = JSON.parse(result);
                const code = rtn.code;
                if (code === '0') {
                    console.log('提交成功');
                    const messageId = (rtn.data || {}).messageId;
                    console.log('messageId=' + messageId);
                } else {
                    console.log(`提交失败: code=${code}, message=${rtn.message}`);
                }
            });
        });

        req.on('error', (e) => {
            console.error('请求异常: ' + e.message);
        });

        req.write(jsonBody);
        req.end();
    }

    /**
     * 生成签名
     *
     * @param {string} password - API账号密码
     * @param {SmsSendRequest} smsRequest - 发送请求参数
     * @param {string} nonce - 一般为时间戳
     * @returns {string} MD5签名字符串
     */
    _generateSign(password, smsRequest, nonce) {
        // 按key字母排序(等价于Java的TreeMap)
        const paramMap = smsRequest.toDict();
        // nonce 加入参数表一起排序
        paramMap.nonce = nonce;
        const sortedKeys = Object.keys(paramMap).sort();

        let sb = '';
        for (const key of sortedKeys) {
            const value = paramMap[key];
            if (value !== null && value !== undefined && String(value).trim() !== '') {
                sb += key;
                sb += value;
            }
        }
        // 追加API账号密码
        const signContent = sb + password;
        return crypto.createHash('md5').update(signContent, 'utf-8').digest('hex').toLowerCase();
    }
}

// 入口
ChuanglanIntsmsDemo.main();

4.接口响应码

状态码描述
0提交成功
101账号不存在
102密码错误
103拉取条数格式错误
104拉取条数不在范围内
105批次编号大于64位
106短信内容长度超过3000字符限制
108手机号码格式错误
109手机号码个数错误,批量提交手机号码不能超过2000个
110余额不足
112产品配置错误
114客户端IP错误
116账号已删除或禁用
118账号不能为空
119账号不在当前节点
123短信内容不能为空
124简介或验证码不能为空
128账号长度超过50位
129产品价格配置错误
130未知异常
131超过日发送上限
132超过月发送上限
134超过反投诉限制
135短信内容不匹配
136短信计费失败
137账号发送类型与当前api接口不匹配
138手机号发送黑名单限制
139whatsApp模板ID匹配错误
140超过日发送金额上限
142新用户需要配置ip白名单
143价格不存在
144模板ID错误或未审核
145超过月发送金额上限
146宵禁时间限制
148通道发送上限
149账户发送开关关闭
150子账号依附计费配置有误
151报价国家未开启
152产品账号报价不存在
153依附计费的主账号不存在
154产品账号计费方式不存在
155账户未开通统一计费
156产品账号已禁用
157账户余额不足
158授信额度不足
159客户未开通统一钱包
160香港营销短信拒收号码
161香港未授权#号sender使用

5.回执状态码

状态码描述
DELIVRD短信发送成功
UNKNOWN未知短信状态
REJECTD短信被短信中心拒绝
MBBLACK目的号码是黑名单号码
SM11网关验证号码格式错误
SM12我方验证号码格式错误
其他网关内部状态
24小时热线 400-9669-253