飞鱼短信是飞鱼云通信为用户提供的一种云通信服务,帮助广大开发者便捷、灵活接入高质量的短信服务。
支持国内短信、国际及港澳台短信,其中,国际及港澳台短信覆盖全球200+国家及地区。常见应用场景:验证码短信(账号注册、登录验证、找回密码、安全提醒等场景),系统通知短信(故障告警、状态提醒、价格调整等场景),会员服务短信(活动通知、业务促销、新品上线、会员关怀等场景)。

- 反对宪法所确定的基本原则的信息;
- 危害国家安全,泄露国家秘密,颠覆国家政权,破坏国家统一的信息;
- 损害国家荣誉和利益的信息;
- 煽动民族仇恨、民族歧视,破坏民族团结的信息;
- 破坏国家宗教政策,宣扬邪教和封建迷信的信息;
- 散布谣言,扰乱社会秩序,破坏社会稳定的信息;
- 假冒银行或银联名义进行诈骗或者敲诈勒索公私财物的信息;
- 散布淫秽、色情、赌博、暴力、凶杀、恐怖内容或者教唆犯罪、传授犯罪方法的信息;
- 非法销售枪支、弹药、爆炸物、走私车、毒品、迷魂药、淫秽物品、假钞假发票或明知是犯罪所得赃物的信息;
- 侮辱或者诽谤他人,侵害他人合法权益的信息;
- 发布可能产生重大负面社会影响的信息;
- 未经他人同意传递商业等信息;
- 发布假中奖、假婚介、假招聘,或者引诱、介绍他人卖淫嫖娼的信息;
- 多次发送干扰他人正常生活的,以及含有其他违反宪法、法律、行政法规禁止性规定内容的信息;
- 从事欺骗或诈骗行为;
- 其他违反国家法律、行政法规和行业政策的行为;
根据短信的应用场景、用途不同,区分为验证码、通知短信、会员服务短信;
短信内容由短信签名、短信正文两部分组成,其中,短信签名需在发送前报备,在发送时使用即可;
短信签名是具体要发送的短信内容的组成部分之一,一般放在短信正文前面,用于标识企业主体或产品业务;用户可以根据账号主体所属机构的业务需求创建符合自身属性的、个性化短信签名;
下行(Message Terminal)是指手机用户收到的短消息;
上行(Message Original)是指手机用户发送的回复内容;
状态报告是指运营商返回的发送结果;
- 请提供推送地址,平台在收到状态报告后会立即推送到指定地址
- 通过调用接口主动获取
- 国内短信长度(签名+正文)不超过70字时,按照1条短信计费;超过70字即为长短信时,按67字/条分隔成多条计费,但会在1条短信内呈现
例如,短信长度为150字,则按照67字/67字/16字分隔成3条计费
- 单次发送的短信长度最长不允许超过500字
- 国内短信必须携带签名,签名符号为【】
- GSM 标准字符按1个字计算,GSM 扩展字符按2个字计算
| 类别 | 字符列表 | 
|---|
| 标准字符 | ! “ # $ % ’ ( ) * + , - . / : ; < = > ? @ _ ¡ £ ¥ § ¿ & ¤ 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z Ä Å Æ Ç É Ñ Ø ø Ü ß Ö à ä å æ è é ì ñ ò ö ù ü Δ Φ Γ Λ Ω Π Ψ Σ Θ Ξ | 
| 扩展字符 | | ^ € { } [ ] ~ \ | 
- 当短信长度不超过160字时,按照1条短信计费。超过160字时为长短信,按153字/条分隔成多条计费。
例如,短信长度为320字,则按照153字/153字/14字分隔成3条计费。
- 汉字、字母、数字、标点符号(不区分全角/半角)以及空格等,都按1个字计算
- 当短信长度不超过70字时,按照1条短信计费。超过70字时为长短信,按67字/条分隔成多条计费
例如,短信长度为150字,则按照67字/67字/16字分隔成3条计费
处于安全考虑,请将贵司公网IP提供给相关对接人员进行报备
 
 
 
 
 
405:请检查请求方法是否正确
415:请检查请求头的Content-Type是否正确
  
  
 
 
 
提交成功:提交到运营商网关成功;
提交失败:提交到运营商网关失败;
发送成功:短信的状态报告显示终端接收成功;
发送失败:短信的状态报告显示终端接收失败; 短信的状态报告有效期在48小时内
  
  
| 更新说明 | 更新时间 | 
|---|
| 新增发送短信加密接口;新增加密推送功能 | 2023-10-28 | 
| 移除短信内容URLEncoder;移除短信发送接口version字段 | 2024-09-27 | 
| 短信上行推送新增smsId字段;移除短信发送接口的smsType字段 | 2025-03-14 | 
- Content-Type: application/json;charset=utf-8
- 编码: UTF-8
- 请求地址: https://api.aiofish.com/rest/sms/sendSms
- 请求方式: POST
  {
      "account": "xxxxxx",
      "password": "aa6f32c0d19832a228ae2c72471c6a49",
      "smsType": "cs",
      "mobile": "12312345678",
      "content": "【飞鱼短信】您的验证码是123456,5分钟内有效。",
      "subCode": "11"
  }   
| 参数 | 数据类型 | 是否必填 | 字段解释 | 
|---|
| account | String | 是 | 对接账号(短信平台提供) | 
| password | String | 是 | 密码(短信平台提供)。生成规则:MD5(password),生成的字符串应全部为小写字母 | 
| mobile | String | 是 | 手机号码(多个以英文逗号隔开),单次提交数量不超过2000个 | 
| content | String | 是 | 短信内容 | 
| subCode | String | 否 | 扩展码,只能为数字。 | 
| smsId | String | 否 | 消息唯一标识ID,用来匹配状态报告,最大可支持32位。(如不填写则短信平台自动生成) | 
| sendTime | String | 否 | 定时发送时间,格式:2020-10-01 12:12:13 | 
{
    "code": 200,
    "smsId": "e4aaea7fb95d40159d1e325df01d9e72",
    "subStat": "r:000",
    "subStatDes": "处理成功",
    "resDetail": [
        {
            "phoneNumber": "12312345678",
            "stat": "r:000",
            "statDes": "提交成功"
        }
    ]
}
| 参数 | 数据类型 | 字段解释 | 
|---|
| code | int | 响应code | 
| smsId | String | 消息唯一标识ID.如果客户端提供则等于请求时的smsId,否则为短信平台自动生成。 | 
| subStat | String | 值为 r:000时表示该请求被成功受理,其他值则表示受理失败 | 
| subStatDes | String | 响应码描述 | 
| resDetail | String | 响应详情 | 
当前接口只对手机号进行加密处理,推荐使用更安全的加密接口!
 
 
- Content-Type: application/json;charset=utf-8
- 编码: UTF-8
- 请求地址: https://api.aiofish.com/rest/sms/sendSmsByEncrypt
- 请求方式: POST
  {
      "account": "xxxxxx",
      "password": "aa6f32c0d19832a228ae2c72471c6a49",
      "mobile": "e86deeb2e7ea254ef1494b83657b01fd",
      "content": "【飞鱼短信】您的验证码是123456,5分钟内有效。",
      "subCode": "11"
  }   
| 参数 | 数据类型 | 是否必填 | 字段解释 | 
|---|
| account | String | 是 | 对接账号(短信平台提供) | 
| password | String | 是 | 密码(短信平台提供)。生成规则:MD5(password),生成的字符串应全部为小写字母 | 
| mobile | String | 是 | 手机号码(多个以英文逗号隔开),单次提交数量不超过2000个。使用AES/ECB/PKCS5Padding模式加密,密钥长度128位。AES加密参考 AesUtil.java | 
| content | String | 是 | 短信内容。 | 
| subCode | String | 否 | 扩展码,字符只能为数字。 | 
| smsId | String | 否 | 消息唯一标识ID,用来匹配状态报告,最大可支持32位。(如不填写则短信平台自动生成) | 
| sendTime | String | 否 | 定时发送时间,格式:2020-10-01 12:12:13 | 
{
    "code": 200,
    "smsId": "e4aaea7fb95d40159d1e325df01d9e72",
    "subStat": "r:000",
    "subStatDes": "处理成功",
    "resDetail": [
        {
            "phoneNumber": "e86deeb2e7ea254ef1494b83657b01fd",
            "stat": "r:000",
            "statDes": "提交成功"
        }
    ]
}
| 参数 | 数据类型 | 字段解释 | 
|---|
| code | int | 响应code | 
| smsId | String | 消息唯一标识ID.如果客户端提供则等于请求时的smsId,否则为短信平台自动生成。 | 
| subStat | String | 值为 r:000时表示该请求被成功受理,其他值则表示受理失败 | 
| subStatDes | String | 响应码描述 | 
| resDetail | String | 响应详情 | 
- Content-Type: application/json;charset=utf-8
- 编码: UTF-8
- 请求地址: https://api.aiofish.com/rest/sms/sendSms/encryption
- 请求方式: POST
  {
    "account": "api003",
    "ts": "1698632973036",
    "bizContent": "10e18d2ebaebdb485cae33dca2604e10706cfa2ba255ba0bedb7ec9f7099",
    "sign": "1f55c5a8b38bc37706bbed532940ae4190814a5c96fe2c3"
}
| 参数 | 数据类型 | 是否必填 | 字段解释 | 
|---|
| account | String | 是 | 对接账号(短信平台提供) | 
| ts | String | 是 | 时间戳。单位:毫秒 | 
| bizContent | String | 是 | 加密后的请求内容。原始数据对象先转为json字符串,然后使用AES进行加密。AES使用AES/ECB/PKCS5Padding模式加密,密钥长度128位。AES加密参考 AesUtil.java | 
| sign | String | 是 | 数字签名。 说明:参数(account,ts,appSecret,bizContent)按照升序拼接,再使用SHA256生成签名。 | 
{
  "mobile": "12312345678",
  "content": "您的验证码为:703319,有效期5分钟",
  "subCode": "11"
}   
| 参数 | 数据类型 | 是否必填 | 字段解释 | 
|---|
| mobile | String | 是 | 手机号码(多个以英文逗号隔开),单次提交数量不超过2000个 | 
| content | String | 是 | 短信内容。 | 
| subCode | String | 否 | 扩展码,只能为数字。 | 
| smsId | String | 否 | 消息唯一标识ID,用来匹配状态报告,最大可支持32位。(如不填写则短信平台自动生成) | 
| sendTime | String | 否 | 定时发送时间,格式:2020-10-01 12:12:13 | 
import com.google.common.base.Joiner;
import org.apache.commons.codec.digest.DigestUtils;
public static String generateSign(String account, String ts, String  bizContent, 
                                            String appSecret) throws Exception {
    Map<String, String> params = new TreeMap<>();
    params.put("account", account);
    params.put("appSecret", appSecret);
    params.put("ts", ts);
    params.put("bizContent", bizContent);
    String str = Joiner.on("&").withKeyValueSeparator("=").join(params);
    return DigestUtils.sha256Hex(str);
}
原始内容拼接:
account=api003&appSecret=ba92fa4836984eb98156e6ec8a6b2454&bizContent=10e18d2ebaebdb485cae33dca2&ts=1698632973036
签名结果:
1f825da81826e47c4dbff9a5c785cb8c141dcb1a5343d3650bfe6794879ef400
{
    "code": 200,
    "smsId": "e4aaea7fb95d40159d1e325df01d9e72",
    "subStat": "r:000",
    "subStatDes": "处理成功"
}
| 参数 | 数据类型 | 字段解释 | 
|---|
| code | int | 响应code | 
| smsId | String | 消息唯一标识ID.如果客户端提供则等于请求时的smsId,否则为短信平台自动生成。 | 
| subStat | String | 值为 r:000时表示该请求被成功受理,其他值则表示受理失败 | 
| subStatDes | String | 响应码描述 | 
- Content-Type: application/json;charset=utf-8
- 编码: UTF-8
- 请求地址: https://api.aiofish.com/rest/sms/batchSendSms
- 请求方式: POST
{
"account": "ZNRX7j",
"password": "14fa0b773a0ca9ca66a9db8fcf1d25",
"mobiles": [
  {
    "mobile": "13000000000",
    "content": "【测试】您的验证码是123456。",
    "templateId": "123"
  },
  {
    "mobile": "13000000001",
    "content": "【测试】您的验证码是654321。",
    "templateId": "123"
  }
],
"subCode": "12",
"smsId": "f5e08fb8d073c7b536f7ccaa9f07e1",
"sendTime": null
} 
| 参数 | 数据类型 | 是否必填 | 字段解释 | 
|---|
| account | String | 是 | 对接账号(短信平台提供) | 
| password | String | 是 | 密码(短信平台提供)。规则:MD5(password),生成的字符串应全部为小写字母 | 
| mobiles | SendObj[] | 是 | 批量发送对象,提交数量不超过200个 | 
| subCode | String | 否 | 扩展码,只能为数字。 | 
| smsId | String | 否 | 消息唯一标识ID,用来匹配状态报告,最大可支持32位。(如不填写则短信平台自动生成) | 
| sendTime | String | 否 | 定时发送时间,格式:2020-10-01 12:12:13 | 
| 参数 | 数据类型 | 是否必填 | 字段解释 | 
|---|
| mobile | String | 是 | 单个手机号码 | 
| content | String | 是 | 完整的短信内容 | 
| templateId | String | 否 | 审核通过的短信模板Id | 
{
  "code": 200,
  "smsId": "e4aaea7fb95d40159d1e325df01d9e72",
  "subStat": "r:000",
  "subStatDes": "处理成功"
}
| 参数 | 数据类型 | 字段解释 | 
|---|
| code | int | 响应code | 
| smsId | String | 消息唯一标识ID.如果客户端提供则等于请求时的smsId,否则为短信平台自动生成。 | 
| subStat | String | 值为 r:000时表示该请求被成功受理,其他值则表示受理失败 | 
| subStatDes | String | 响应码描述 | 
- Content-Type: application/json;charset=utf-8
- 编码: UTF-8
- 请求地址: https://api.aiofish.com/rest/sms/batchSendSms/encryption
- 请求方式: POST
  {
    "account": "api003",
    "ts": "1698632973036",
    "bizContent": "10e18d2ebaebdb485cae33dca2604e10706cfa2ba255ba0bedb7ec9f7099",
    "sign": "1f55c5a8b38bc37706bbed532940ae4190814a5c96fe2c3"
}
| 参数 | 数据类型 | 是否必填 | 字段解释 | 
|---|
| account | String | 是 | 对接账号(短信平台提供) | 
| ts | String | 是 | 时间戳。单位:毫秒 | 
| bizContent | String | 是 | 加密后的请求内容。原始数据对象先转为json字符串,然后使用AES进行加密。AES使用AES/ECB/PKCS5Padding模式加密,密钥长度128位。AES加密参考 AesUtil.java | 
| sign | String | 是 | 数字签名。 说明:参数(account,ts,appSecret,bizContent)按照升序拼接,再使用SHA256生成签名。 | 
{
"mobiles": [
  {
    "mobile": "13000000000",
    "content": "【测试】您的验证码是123456。"
  },
  {
    "mobile": "13000000001",
    "content": "【测试】您的验证码是654321。"
  }
],
"subCode": "12",
"smsId": "f5e08fb8d073c7b536f7ccaa9f07e1",
"sendTime": null
} 
| 参数 | 数据类型 | 是否必填 | 字段解释 | 
|---|
| mobiles | SendObj[] | 是 | 批量发送对象,提交数量不超过200个 | 
| subCode | String | 否 | 扩展码,只能为数字。 | 
| smsId | String | 否 | 消息唯一标识ID,用来匹配状态报告,最大可支持32位。(如不填写则短信平台自动生成) | 
| sendTime | String | 否 | 定时发送时间,格式:2020-10-01 12:12:13 | 
| 参数 | 数据类型 | 是否必填 | 字段解释 | 
|---|
| mobile | String | 是 | 单个手机号码 | 
| content | String | 是 | 完整的短信内容 | 
import com.google.common.base.Joiner;
import org.apache.commons.codec.digest.DigestUtils;
public static String generateSign(String account, String ts, String  bizContent, 
                                            String appSecret) throws Exception {
    Map<String, String> params = new TreeMap<>();
    params.put("account", account);
    params.put("appSecret", appSecret);
    params.put("ts", ts);
    params.put("bizContent", bizContent);
    String str = Joiner.on("&").withKeyValueSeparator("=").join(params);
    return DigestUtils.sha256Hex(str);
}
原始内容拼接:
account=api003&appSecret=ba92fa4836984eb98156e6ec8a6b2454&bizContent=10e18d2ebaebdb485cae33dca2&ts=1698632973036
签名结果:
1f825da81826e47c4dbff9a5c785cb8c141dcb1a5343d3650bfe6794879ef400
{
  "code": 200,
  "smsId": "e4aaea7fb95d40159d1e325df01d9e72",
  "subStat": "r:000",
  "subStatDes": "处理成功"
}
| 参数 | 数据类型 | 字段解释 | 
|---|
| code | int | 响应code | 
| smsId | String | 消息唯一标识ID.如果客户端提供则等于请求时的smsId,否则为短信平台自动生成。 | 
| subStat | String | 值为 r:000时表示该请求被成功受理,其他值则表示受理失败 | 
| subStatDes | String | 响应码描述 | 
- 请求地址: https://api.aiofish.com/rest/sms/getBalance
- 请求方式: GET
https://api.aiofish.com/rest/sms/getBalance?account=J10003&password=26dad7f364507df1
{
    "revStat": "r:000",
    "revStatDes": "您的短信余额为:2670 条",
    "code": 200,
    "demo": null
}
- 请求地址: https://api.aiofish.com/rest/sms/getReport
- 请求方式: GET
https://api.aiofish.com/rest/sms/getReport?account=J10003&password=26dad7f364507df18f3841c
{
    "subStat": "r:000",
    "subStatDes": "获取状态报告记录数:1",
    "code": 200,
    "resDetail": [
        {
            "smsId": "e4aaea7fb95d40159d1e325df01d9e72",
            "phoneNumber": "12312345678",
            "stat": "r:004",
            "statDes": "REJECTD",
            "revTime": 1636429743000
        }
    ]
}
- 请求地址: https://api.aiofish.com/rest/sms/getReply
- 请求方式: GET
 https://api.aiofish.com/rest/sms/getReply?account=J10003&password=26dad7f364507df18f3841cc
{
    "revStat": "r:000",
    "revStatDes": "获取上行短信条数:1",
    "code": 200,
    "resDetail": [
        {
            "phoneNumber": "12312345678",
            "content": "收到",
            "subCode": "11",
            "revTime": 1616429743000,
            "demo": null
        }
    ]
}
- Content-Type: application/x-www-form-urlencoded
- 编码: UTF-8
- 推送地址: 客户需提供状态报告以及上行推送地址
- 推送频次: 推送失败将会在5分钟、10分钟和1小时后再次尝试推送
- 推送结果: 客户正常处理后返回0。返回其他任何数据系统都会识别为推送失败
- 推送方式: 单条推送
| 参数 | 数据类型 | 是否必填 | 字段解释 | 
|---|
| phoneNumber | String | 是 | 手机号 | 
| smsId | String | 是 | 消息Id | 
| stat | Int | 是 | 状态。 0:成功,其他为失败 | 
| statDes | String | 是 | 发送失败错误码 | 
| revTime | Int64 | 是 | 接收时间,毫秒 | 
| 参数 | 数据类型 | 是否必填 | 字段解释 | 
|---|
| phoneNumber | String | 是 | 手机号 | 
| content | String | 是 | 上行内容 | 
| subCode | String | 否 | 扩展码 | 
| smsId | String | 否 | 上行对应的短信消息ID。 更新于2025-03-14 | 
当前推送方式只对手机号进行加密处理,推荐使用更安全的加密推送方式!
 
 
- Content-Type: application/x-www-form-urlencoded
- 编码: UTF-8
- 推送地址: 客户需提供状态报告以及上行推送地址
- 推送频次: 推送失败将会在1分钟、5分钟、10分钟和1小时后再次尝试推送
- 推送结果: 客户正常处理后返回0。返回其他任何数据系统都会识别为推送失败
- 推送方式: 单条推送
| 参数 | 数据类型 | 是否必填 | 字段解释 | 
|---|
| phoneNumber | String | 是 | 使用AES/ECB/PKCS5Padding模式加密,密钥长度128位。AES解密参考 AesUtil.java | 
| smsId | String | 是 | 消息Id | 
| stat | Int | 是 | 状态。 0:成功,其他为失败 | 
| statDes | String | 是 | 发送失败错误码 | 
| revTime | Int64 | 是 | 接收时间,毫秒 | 
| 参数 | 数据类型 | 是否必填 | 字段解释 | 
|---|
| phoneNumber | String | 是 | 使用AES/ECB/PKCS5Padding模式加密,密钥长度128位。AES解密参考 AesUtil.java | 
| content | String | 是 | 上行内容 | 
| subCode | String | 否 | 扩展码 | 
| smsId | String | 否 | 上行对应的短信消息ID。 更新于2025-03-14 | 
- Content-Type: application/json;charset=utf-8
- 编码: UTF-8
- 推送地址: 客户需提供状态报告以及上行推送地址
- 推送频次: 推送失败将会在1分钟、5分钟、10分钟和1小时后再次尝试推送
- 推送结果: 客户正常处理后返回0。返回其他任何数据系统都会识别为推送失败
- 推送方式: 单条推送
  {
    "account": "api003",
    "ts": "1698632973036",
    "bizContent": "10e18d2ebaebdb485cae33dca2604e10706cfa2ba255ba0bedb7ec9f7099",
    "sign": "1f55c5a8b38bc37706bbed532940ae4190814a5c96fe2c3"
}
| 参数 | 数据类型 | 是否必填 | 字段解释 | 
|---|
| account | String | 是 | 对接账号(短信平台提供) | 
| ts | String | 是 | 时间戳。单位:毫秒 | 
| bizContent | String | 是 | 加密后的请求内容。原始数据对象先转为json字符串,然后使用AES进行加密。AES使用AES/ECB/PKCS5Padding模式加密,密钥长度128位。AES加密参考 AesUtil.java | 
| sign | String | 是 | 数字签名。 说明:参数(account,ts,appSecret,bizContent)按照升序拼接,再使用SHA256生成签名。 | 
import com.google.common.base.Joiner;
import org.apache.commons.codec.digest.DigestUtils;
public static String generateSign(String account, String ts, String  bizContent, 
                                            String appSecret) throws Exception {
    Map<String, String> params = new TreeMap<>();
    params.put("account", account);
    params.put("appSecret", appSecret);
    params.put("ts", ts);
    params.put("bizContent", bizContent);
    String str = Joiner.on("&").withKeyValueSeparator("=").join(params);
    return DigestUtils.sha256Hex(str);
}
原始内容拼接:
account=api003&appSecret=ba92fa4836984eb98156e6ec8a6b2454&bizContent=10e18d2ebaebdb485cae33dca2&ts=1698632973036
签名结果:
1f825da81826e47c4dbff9a5c785cb8c141dcb1a5343d3650bfe6794879ef400
{
    "stat": 6,
    "smsId": "03e2c9e81a54416ba2a046eac6f52b63",
    "phoneNumber": "17530663764",
    "statDes": "REJECTD",
    "revTime": 1698636405820
}
| 参数 | 数据类型 | 是否必填 | 字段解释 | 
|---|
| phoneNumber | String | 是 | 手机号 | 
| smsId | String | 是 | 消息Id | 
| stat | Int | 是 | 状态。 0:成功,其他为失败 | 
| statDes | String | 是 | 发送失败错误码 | 
| revTime | Int64 | 是 | 接收时间,毫秒 | 
{
    "phoneNumber": "17530663764",
    "content": "R",
    "subCode": "123",
    "smsId": "8b8a8939d5424bd0ad60aea59e995434"
}
| 参数 | 数据类型 | 是否必填 | 字段解释 | 
|---|
| phoneNumber | String | 是 | 手机号 | 
| content | String | 是 | 上行内容 | 
| subCode | String | 否 | 扩展码 | 
| smsId | String | 否 | 上行对应的短信消息ID。 更新于2025-03-14 | 
| code | 错误码 | 错误描述 | 
|---|
| 200 | r:000 | 处理成功 | 
| 421 | p:001 | 内容错误 | 
| 411 | p:002 | 号码错误 | 
| 401 | p:003 | 账号或密码错误 | 
| 102 | p:004 | 余额不足 | 
| 412 | p:006 | 提交号码数量过多 | 
| 451 | p:007 | 业务类型错误 | 
| 111 | p:008 | 没有权限 | 
| 121 | p:010 | 访问速度过快 | 
| 122 | p:011 | 解密失败 | 
| 999 | p:999 | 其他错误 | 
- Content-Type: application/json;charset=utf-8
- appKey: 接入账号,系统平台提供。
- appSecret: 接入密钥,系统平台提供。
- ts: 当前时间戳,精确到毫秒。
- 所有接口请求的header中必须包含签名字段:x-sign,该字段使用相关参数按照指定拼接规则通过MD5摘要算法得到。
 String sign = MD5(String.format("%s,%s,%s",appKey,ts,appSecret));
- 请求地址: https://api.aiofish.com/rest/vsms/v1/tpl
- 请求方式: POST
- Content-Type: multipart/form-data
- 以http表单形式单次上传多个附件,key为表单的“file“字段。除了文件数据外的请求参数转换为Json字符串,key为表单的“data“字段
| 参数名 | 必填 | 参数类型 | 说明 | 
|---|
| appKey | 是 | String | 系统分配 | 
| ts | 是 | String | 时间戳 | 
| title | 是 | String | 模板标题 | 
| content | 是 | Array[ContentList> | 模板内容。内容按照帧的形式展示,每一帧包含文字或其他资源 | 
| 参数名 | 必填 | 参数类型 | 说明 | 
|---|
| orderBy | 是 | Int | 代表该内容在本帧内的顺序 | 
| frameIndex | 是 | Int | 代表帧所在的位置 | 
| extType | 是 | Int | 内容类型。1:文字内容,2:文件资源 | 
| text | 是 | String | 当类型为2时填写文件名。当类型为1时该字段为文字内容,当内容中含有可变参数时,则用#p_1#,#p_2#..#p_5# 占位,变量非必须使用,最多使用5个变量,每个变量值的长度最多不超过15位 | 
 curl  --request POST 'https://api.aiofish.com/rest/vsms/v1/tpl' 
 --header 'x-sign: 39dd91319d32b36def6272e1b9' 
 --form 'data="{\"appKey\":\"xxxxx\",\"ts\":\"1638805414651\",\"title\":\"测试\",\"content\":[{\"orderBy\":1,\"frameIndex\":1,\"extType\":2,\"text\":\"aaa.jpg\"},{\"orderBy\":2,\"frameIndex\":1,\"extType\":1,\"text\":\"【测试】内容测试\"}]}"' 
 --form 'file=@"aaa.jpg"'
| 字段名 | 字段类型 | 说明 | 
|---|
| code | String | 错误码。‘success’:成功,其他失败 | 
| tplId | String | 模板ID。当code为‘success’请求成功时生成 | 
- 请求地址: https://api.aiofish.com/rest/vsms/v1/tpl/status
- 请求方式: GET
| 参数名 | 必填 | 参数类型 | 说明 | 
|---|
| appKey | 是 | String | 系统分配 | 
| ts | 是 | String | 时间戳 | 
| tplId | 是 | String | 查询的模板ID | 
curl  --request GET 'https://api.aiofish.com/rest/vsms/v1/tpl/status?appKey=test11&ts=1638805414651&tplId=4176a024bf6a381e5a38fe5f866' \
 --header 'x-sign: 39dd91319d32b36def6272e1b9'
| 字段名 | 字段类型 | 说明 | 
|---|
| code | String | 错误码.success:成功,其他失败。 | 
| tplId | String | 模板ID | 
| auditStatus | Int | 状态。100:待审核,200:审核通过,400:审核未通过 | 
| auditReason | String | 审核结果说明 | 
- 请求地址: https://api.aiofish.com/rest/vsms/v1/message
- 请求方式: POST
| 参数名 | 必填 | 参数类型 | 说明 | 
|---|
| appKey | 是 | String | 系统分配 | 
| ts | 是 | String | 时间戳 | 
| tplId | 是 | String | 模板ID | 
| mobiles | 是 | Array[String] | 手机号码列表 | 
| uuid | 否 | String | 用户端消息ID | 
| scheduleTime | 否 | String | 定时发送时间,必须大于当前时间。格式:yyyy-MM-dd HH:mm:ss | 
curl  --request POST 'https://api.aiofish.com/rest/vsms/v1/message' \
--header 'x-sign: 39dd91319d32b36def6272e1b9' \
--header 'Content-Type: application/json' \
--data-raw '{
    "appKey": "test11",
    "ts": "1638805414651",
    "tplId": "4176a024bf6a381e5a38fe5f866",
    "mobiles": [
        "180******43"
    ]
}'
| 字段名 | 字段类型 | 说明 | 
|---|
| code | String | 错误码。success:成功,其他失败 | 
| msgId | String | 消息ID。后续推送状态报告使用此ID | 
- 请求地址: https://api.aiofish.com/rest/vsms/v1/message/vars
- 请求方式: POST
| 参数名 | 必填 | 参数类型 | 说明 | 
|---|
| appKey | 是 | String | 系统分配 | 
| ts | 是 | String | 时间戳 | 
| tplId | 是 | String | 模板ID | 
| mobiles | 是 | Array[SendVar] | 手机号码列表 | 
| uuid | 否 | String | 用户端消息ID | 
| scheduleTime | 否 | String | 定时发送时间,必须大于当前时间。格式:yyyy-MM-dd HH:mm:ss | 
| 参数名 | 必填 | 参数类型 | 说明 | 
|---|
| phone | 是 | String | 手机号码 | 
| vars | 是 | Array[String] | 变量列表。最多使用5个变量,每个变量值的长度最多不超过15位 | 
curl --request POST 'https://api.aiofish.com/rest/vsms/v1/message/vars' \
--header 'x-sign: 39dd91319d32b36def6272e1b9' \
--header 'Content-Type: application/json' \
--data-raw '{
    "appKey": "test11",
    "ts": "1638805414651",
    "tplId": "4176a024bf6a381e5a38fe5f866",
    "mobiles": [
        {
            "phone": "180****43",
            "vars": [
                "test"
            ]
        }
    ]
}'
| 字段名 | 字段类型 | 说明 | 
|---|
| code | String | 错误码。success:成功,其他失败 | 
| msgId | String | 消息ID。后续推送状态报告使用此ID | 
- Content-Type: application/json
- 编码: UTF-8
- 推送地址: 客户需提供状态报告、上行推送以及模板状态推送地址
- 推送频次: 推送失败将会在5分钟、10分钟和1小时后再次尝试推送
- 推送结果: 客户正常处理后返回字符串0。返回其他任何数据,系统会识别为推送失败
- 推送方式: 单条推送
| 参数 | 数据类型 | 是否必填 | 字段解释 | 
|---|
| phone | String | 是 | 手机号 | 
| msgId | String | 是 | 消息Id | 
| state | Int | 是 | 状态。0:成功,其他为失败 | 
| statDes | String | 是 | 发送失败错误码 | 
| revTime | String | 是 | 接收时间 | 
{
    "msgId":"88f07db153f24a638779",
    "phone":"18000000000",
    "state":0,
    "statDes":"DELIVRD",
    "revTime":"2021-12-06T19:00:00"
}
| 参数 | 数据类型 | 是否必填 | 字段解释 | 
|---|
| tplId | String | 是 | 模板ID | 
| state | Int | 是 | 200:审核通过,400:审核未通过 | 
| reason | String | 否 | 审核结果说明 | 
{
   "tplId":"88f07db153f24a638779",
   "state":200,
   "reason":"ok"
}
| code | 错误说明 | 
|---|
| success | 请求成功 | 
| invalid_data | 无效数据 | 
| invalid_sign | 无效签名 | 
| invalid_appkey | 无效APPKEY | 
| invalid_ts | 无效时间戳 | 
| invalid_title | 无效标题 | 
| invalid_tpl | 无效模板 | 
| invalid_content | 无效内容 | 
| invalid_resource | 无效的文件数据 | 
| resource_limit | 文件数据大小超限 | 
| invalid_mobile | 无效手机号 | 
| permission | 无权限 | 
| authorization | 身份验证失败 | 
| mobile_limit | 号码数量超过限制 | 
| request_limit | 请求次数超过限制 | 
| error | 处理异常 | 
- Content-Type: application/json;charset=utf-8
- appKey: 接入账号,系统平台提供。
- appSecret: 接入密钥,系统平台提供。
- ts: 当前时间戳,精确到毫秒。
- 所有接口请求的header中必须包含签名字段:x-sign,该字段使用相关参数按照指定拼接规则通过MD5摘要算法得到。
 String sign = MD5(String.format("%s,%s,%s",appKey,ts,appSecret));
- 请求地址: https://api.aiofish.com/rest/isms/sendIsms
- 请求方式: POST
| 参数名 | 必填 | 参数类型 | 说明 | 
|---|
| appKey | 是 | String | 系统分配 | 
| ts | 是 | String | 时间戳 | 
| tplId | 是 | String | 模板ID | 
| mobiles | 是 | Array[String] | 手机号码列表,号码需要加国际电话区号 | 
| uuid | 否 | String | 用户端消息ID | 
| scheduleTime | 否 | String | 定时发送时间,必须大于当前时间。格式:yyyy-MM-dd HH:mm:ss | 
curl  --request POST 'https://api.aiofish.com/rest/isms/sendIsms' \
--header 'x-sign: 39dd91319d32b36def6272e1b9' \
--header 'Content-Type: application/json' \
--data-raw '{
    "appKey": "test11",
    "ts": "1638805414651",
    "content": "hello! test sms",
    "mobiles": [
        "86180******43"
    ]
}'
| 字段名 | 字段类型 | 说明 | 
|---|
| code | String | 错误码。success:成功,其他失败 | 
| msgId | String | 消息ID。后续推送状态报告使用此ID | 
- Content-Type: application/json
- 编码: UTF-8
- 推送地址: 客户需提供状态报告、上行推送以及模板状态推送地址
- 推送频次: 推送失败将会在5分钟、10分钟和1小时后再次尝试推送
- 推送结果: 客户正常处理后返回字符串0。返回其他任何数据,系统会识别为推送失败
- 推送方式: 单条推送
| 参数 | 数据类型 | 是否必填 | 字段解释 | 
|---|
| mobile | String | 是 | 手机号 | 
| msgId | String | 是 | 消息Id | 
| state | Int | 是 | 状态。0:成功,其他为失败 | 
| statDes | String | 是 | 发送失败错误码 | 
| revTime | String | 是 | 接收时间 | 
{
    "msgId":"88f07db153f24a638779",
    "mobile":"85212341234",
    "state":0,
    "statDes":"DELIVRD",
    "revTime":"2021-12-06 19:00:00"
}
| code | 错误描述 | 
|---|
| success | 请求成功 | 
| invalid_data | 无效数据 | 
| invalid_sign | 无效签名 | 
| invalid_appkey | 无效APPKEY | 
| invalid_ts | 无效时间戳 | 
| invalid_tpl | 无效模板 | 
| invalid_mobile | 无效手机号 | 
| permission | 无权限 | 
| authorization | 身份验证失败 | 
| mobile_limit | 号码数量超过限制 | 
| request_limit | 请求次数超过限制 | 
| error | 未知错误 |