通过API发送短信

更新时间:
复制 MD 格式

短信服务提供短信发送、发送状态查询等API接口,您可以通过调用API接口申请签名和模板,并给目标用户发送短信。

您可以根据业务需要和自身情况选择合适的方式调用短信服务API:

  • 阿里云OpenAPI 开发者门户

    适用于习惯交互式操作界面的场景,或者初次使用阿里云产品的开发者用户。您可以通过OpenAPI开发者门户调试和获取SDK请求示例。

  • 短信服务SDK

    支持多种编程语言,包括JavaGoC#PHPNode.js/TypeScriptPython。使用SDK集成短信服务,可提升您使用短信服务的开发效率。

    如果您是首次接入短信服务或编程经验有限,推荐直接使用SDK方式集成。SDK已封装签名认证、超时处理、自动重试等底层逻辑,您只需关注业务参数(手机号、签名、模板)即可快速完成集成,无需理解复杂的签名算法和请求格式。

  • 自定义封装API调用(不推荐)

    阿里云SDK已经封装了签名、超时、重试等机制,我们建议您使用SDK进行集成,降低开发成本。自行封装API调用需要您理解签名算法、处理超时重试、管理请求格式等底层细节,对编程新手而言开发成本较高。如果您确有特殊定制需求且熟悉签名机制,可参见SendSms签名示例代码

本文将以SDK的方式引导您使用短信服务。您可以先通过OpenAPI 开发者门户,查看、体验短信服务API后,根据本文指引开始集成短信服务API。整体流程:

image

准备工作

准备事项

说明

相关文档

账号注册

实名认证

因短信签名实名制要求,使用短信服务必须提供企业资质信息。

  • 个人认证:表示账号持有者是个人,短信服务不支持“个人资质”的签名实名制报备,推荐您使用免资质签名模板申请的短信认证产品。若您已有企业资质,可将阿里云账号升级为“企业认证”或添加“他用”企业资质。

  • 企业认证:表示账号持有者是企业或政府部门,需提供自用或他用企业资质使用短信服务。

重要

在当前的短信签名实名制要求下,个人账号的自用资质无法通过签名实名制报备,个人用户请使用短信认证产品或升级为企业认证账号。

使用须知

服务开通

登录短信服务控制台,开通短信服务。

用户权限

说明

阿里云主账号拥有较高权限,建议您通过RAM用户进行API调用和日常运维。

您可以通过RAM控制台,单击RAM用户名称查看用户权限。请确保您所调用APIRAM用户已有短信服务相关权限:

  • AliyunDysmsFullAccess:管理短信服务的权限。

创建RAM用户

管理RAM用户的权限

自定义授权信息

AccessKey ID

您可以登录RAM控制台,单击RAM用户名称查看AccessKey ID

创建AccessKey

AccessKey Secret

创建后不支持二次查看。若本地无备份,建议重新创建一对AccessKey使用。

设置预警

为保障您的业务稳定和资金安全,建议您登录控制台通用设置-国内消息设置页面,设置联系人并开启和配置验证码防盗刷监控发送量预警套餐包余量预警发送频率预警等。当触发预警时,平台会通知到联系人,联系人可第一时间收到预警通知后及时处理。

说明

建议您阅读验证码防盗刷,了解更多验证码盗刷的防御方式。

发送量预警

套餐包余量预警

发送频率预警

环境配置

本文以Java语言为例,进行后续操作。更多语言及其SDK安装方式,请参见安装与使用教程

  1. 检查Java环境:您的Java版本需高于Java 8。Java环境配置的方法,请参见Windows搭建Java开发环境

  2. 安装SDK:请通过配置Maven依赖,完成短信服务SDK的安装。

    请打开Maven项目的pom.xml文件,在<dependencies>标签内添加以下信息并将 the-latest-version 替换为最新版本号。保存后请重新加载Maven依赖。

    <dependency>
      <groupId>com.aliyun</groupId>
      <artifactId>dysmsapi20170525</artifactId>
      <!-- 请将 'the-latest-version' 替换为最新版本号:https://mvnrepository.com/artifact/com.aliyun/dysmsapi20170525 -->
      <version>the-latest-version</version>
    </dependency>

    SDK 版本说明

    Java 短信服务 SDK 有 V2.0 和 V1.0 两个版本,请优先使用 V2.0:

    版本

    Maven artifactId

    推荐状态

    V2.0(推荐)

    dysmsapi20170525

    推荐使用,功能完整,持续维护

    V1.0(不推荐)

    alibabacloud-dysmsapi20170525

    可用,但不再推荐

    V2.0 SDK 最低兼容 JDK 1.8。本文示例使用 V2.0 SDK(artifactId:dysmsapi20170525)。

    非 Maven 工程:如果工程不使用 Maven,需手动下载 SDK 及其全部依赖 JAR 包,请访问 Maven 仓库获取最新版本信息。

    其他语言 SDK 安装

    • PHP SDK:安装时若提示依赖缺失,执行以下命令补全依赖:

      composer require alibabacloud/tea-utils
    • VB6 等老旧环境:官方 SDK 不支持 VB6.0 等老旧开发环境,建议升级开发环境,或使用阿里云 CLI 工具完成调用。

  3. 配置环境变量:为避免代码中显式编码访问密钥(AccessKey)而造成泄露,建议您把AccessKey配置到环境变量,通过环境变量进行读取。配置后请重启或刷新您的编译运行环境,包括IDE、命令行界面、其他桌面应用程序及后台服务,以确保最新的系统环境变量成功加载。

  4. 配置代理(可选):如果您需要通过代理服务器访问,可通过SDK进行配置,请参见代理配置

API基本信息

短信服务所提供的API基本信息参见如下:

接口版本

2017-05-25

接口风格

RPC

服务接入点

(Endpoint)

中国站请使用 dysmsapi.aliyuncs.com

HTTP调用使用端口为80,HTTPS调用使用端口为443

网络访问与 Endpoint 配置说明

  • 接入方式:短信 API 仅支持 RESTful/OpenAPI 调用,不支持 SOAP/WSDL 协议,也不支持通过浏览器直接访问或拼接 Action 路径(如 /SendSms)方式调用。

  • IP 地址动态性:Endpoint 域名对应的 IP 地址不固定,会动态变更。网络安全组或防火墙规则请放行域名,不要基于固定 IP 配置白名单。若网络环境仅支持 IP 白名单,需自行解析域名并定期更新 IP 列表。

  • 公网访问:调用短信 API 无需额外配置 IP 白名单,服务器能访问公网即可正常调用。

  • RegionIdRegionId 参数可设置为任意地域(如 cn-hangzhou),不影响国内短信的实际发送效果。

建议您在调用API接口前,阅读接口参数规范与使用说明。在线调试 | API文档

API调用流程

image
  1. 申请短信资质:使用SubmitSmsQualification接口,资质信息需遵守资质材料说明资质审核通过后才可以申请短信签名

    • 受短信签名实名制报备要求影响,当前资质审核工单量增长快速,审核时间可能会延长,请耐心等待,预计2个工作日内完成

    • 您可以选择使用API接口查看审核状态:使用QuerySmsQualificationRecord接口查询资质列表,并使用出参WorkOrderId调用QuerySingleSmsQualification接口查询指定资质的审核状态。

  2. 申请短信签名:使用CreateSmsSign接口,签名信息需遵守短信签名规范签名审核通过后才可以申请模板。

    说明

    调用CreateSmsSign接口时,QualificationId(资质ID)为必填参数。请确保已完成资质审核并获取资质ID后再调用该接口。

    • 如果您需要申请的签名用途为他用,则需在申请签名时上传委托授权书,建议您在申请短信签名前根据授权书填写规范调用CreateSmsAuthorizationLetter接口创建授权委托书。

    • 审核预计2个小时内完成(审核工作时间:周一至周日9:00~21:00,法定节假日顺延)。

    • 您可以选择使用接口或回执消息查看审核状态:

      API接口

      使用GetSmsSign接口查询签名状态,或使用QuerySmsSignList接口查询签名列表,根据出参AuditStatus判断。

      回执消息

      通过配置回执并开发对接,具体操作请参见配置回执消息,仅支持HTTP批量推送模式。

      SignSmsReport(签名审核状态)

    • 签名实名制报备:新增签名将在审核通过后自动提交报备,存量签名请在签名管理页面检查后手动提交报备。未报备的签名会被运营商拦截发送操作说明

      重要

      在未完全完成报备之前,短信可能会发送失败,返回错误码如下:

      • PORT_NOT_REGISTERED:当前使用端口号尚未完成企业实名制报备流程。

      • 运营商实名报备流程平均需要5-7个工作日,基于近期观测,部分运营商实名报备流程需要7-10个工作日,但运营商未对此时效进行承诺,实际可能需要更长时间。请合理规划业务计划,并在正式使用前提前申请相关资质和签名,预留时间进行发送测试,以确保在正式使用前有充足的时间完成实名报备。

      若报备失败请按照控制台报备结果详情指引进行操作,详情请参见签名实名制报备

  3. 申请短信模板:使用CreateSmsTemplate接口,模板内容需遵守短信模板规范模板审核通过后才可以发送短信。

    说明

    调用CreateSmsTemplate接口时,RelatedSignName(关联签名名称)为必填参数。请确保已有审核通过的签名,并通过该参数指定签名名称。

    • 申请短信模板时关联的签名仅供审核使用,与实际发送短信时使用的签名无关。

    • 国内短信模板与国际/港澳台短信模板不通用。

    • 审核预计2个小时内完成(审核工作时间:周一至周日9:00~21:00,法定节假日顺延)。

    • 您可以选择使用接口或回执消息查看审核状态:

      API接口

      使用GetSmsTemplate接口查询模板状态,或使用QuerySmsTemplateList接口查询模板列表,根据出参AuditStatus判断。

      回执消息

      通过配置回执并开发对接,具体操作请参见配置回执消息,仅支持HTTP批量推送模式。

      TemplateSmsReport(模板审核状态)

  4. 发送短信:使用SendSms接口,或使用SendBatchSms接口批量发送短信。

    • 建议您等待签名报备状态变更为“已报备待验证”后再批量发送,您可使用三大运营商的手机号少量多次使用该签名发送验证码、通知短信进行测试。在系统探测期内,建议根据自身情况尽可能多测试发送,若实际测试发送的短信成功率符合预期,则报备状态将变更为“报备成功”。若报备状态不为“报备成功”,请根据报备验证环节内相关指引进行操作。

    • 发送短信前确保您账户余额充足。更多详情,请参见计费概述

  5. 查看短信发送详情:您可使用接口或回执消息查看短信发送详情。

    API接口

    使用QuerySendDetails接口查询短信发送状态。

    回执消息

    通过配置回执并开发对接,具体操作请参见配置回执消息。支持以下两种方式:

    SmsReport(状态报告接收):轻量消息队列消费模式 | HTTP批量推送模式

  6. 获取用户回复内容:您发送短信后,用户回复的短信内容即为上行短信,需配置回执消息获取。

    回执消息

    通过配置回执并开发对接,具体操作请参见配置回执消息。支持以下两种方式:

    SmsUp(上行消息接收):轻量消息队列消费模式 | HTTP批量推送模式

更多接口信息,请参见API概览

代码示例

使用SDK发送短信(调用SendSms接口)的代码示例如下,请根据注释完成参数填写。

package com.aliyun.sample;

import com.aliyun.teaopenapi.models.Config;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import static com.aliyun.teautil.Common.toJSONString;

public class Sample {
    public static Client createClient() throws Exception {
        Config config = new Config()
                // 配置 AccessKey ID,请确保代码运行环境设置了环境变量。
                .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                // 配置 AccessKey Secret,请确保代码运行环境设置了环境变量。
                .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
                // System.getenv()方法表示获取系统环境变量,请配置环境变量后,在此填入环境变量名称,不要直接填入AccessKey信息。
        
        // 配置 Endpoint
        config.endpoint = "dysmsapi.aliyuncs.com";

        return new Client(config);
    }

    public static void main(String[] args) throws Exception {
        // 初始化请求客户端
        Client client = Sample.createClient();

        // 构造请求对象,请填入请求参数值
        SendSmsRequest sendSmsRequest = new SendSmsRequest()
                .setPhoneNumbers("1390000****")
                .setSignName("阿里云")
                .setTemplateCode("SMS_15305****")
                .setTemplateParam("{\"name\":\"张三\",\"number\":\"1390000****\"}");

        // 获取响应对象
        SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);

        // 响应包含服务端响应的 body 和 headers
        System.out.println(toJSONString(sendSmsResponse));
    }
}

SDK 集成最佳实践

集成 SDK 时请注意以下常见问题,避免影响功能或性能:

Client 复用(重要)

Client 对象应全局初始化一次,作为单例长期复用。禁止在每次发送短信时重新创建 Client 实例,否则会产生不必要的连接建立开销,影响发送性能。

超时配置

建议将连接超时(connectTimeout)和读取超时(readTimeout)均设置为 1000 毫秒(1 秒)以上,防止网络波动导致同步调用长时间阻塞线程:

Config config = new Config()
    .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
    .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
    .setConnectTimeout(1000)   // 连接超时,单位毫秒,建议 ≥ 1000
    .setReadTimeout(1000);     // 读取超时,单位毫秒,建议 ≥ 1000
config.endpoint = "dysmsapi.aliyuncs.com";

异步调用注意

  • Python SDK:在非主线程中调用时,请使用 async 异步方法;在非主线程中使用同步方法可能引发事件循环问题。

  • Java SDK:使用异步调用时,不要通过 try-with-resources 方式自动关闭 Client;需等待 CompletableFuture 返回结果后再关闭 Client,否则响应数据可能丢失。

响应对象序列化

Druid 的 JSONUtils 不支持直接序列化 SDK 响应对象,请使用以下方式之一处理响应:

  • 调用 response.getBody() 获取响应体

  • 使用 FastJSON 或 Jackson 序列化响应对象

环境变量生效

配置 ALIBABA_CLOUD_ACCESS_KEY_ID 等 AK 环境变量后,必须重启 IDE、命令行窗口或后台服务才能使新配置生效;否则 System.getenv() 仍会返回旧值或空值。

您可以访问 OpenAPI 门户,查看各语言 SDK 请求完整示例。如果您需要自行封装请求来进行API调用,请参见SendSms签名示例代码

常见问题

Q:更换短信签名后为什么发送的还是旧签名?

实际发送的签名由 API 请求参数 SignName 的值决定,与控制台模板审核时关联的签名配置无关。更换签名后,必须同步修改业务代码中调用 SendSms 接口时传入的 SignName 参数值为新签名名称;仅在控制台修改配置不会影响发送结果。

说明
  • 新签名需审核通过并完成实名制报备后方可正常使用。

  • 签名报备初期发送成功率可能有波动,属正常的系统探测阶段现象,报备验证通过后将自动稳定。

Q:AccessKey、签名名称和模板 CODE 在哪里获取?

参数

获取位置

注意事项

AccessKey ID

RAM 控制台 — 创建 RAM 用户后获取

同一账号下所有签名/模板共用一对 AK,无需分别申请;AK 创建后立即生效,无需审核

AccessKey Secret

创建时立即保存

创建后不支持再次查看;遗失需重新创建 AccessKey

签名名称(SignName)

短信服务控制台 — 签名管理页面

须与 API 传参完全一致,包括括号等标点符号

模板 CODE(TemplateCode)

短信服务控制台 — 模板管理页面

格式为 SMS_ 开头

说明

第三方平台配置中的"APPkey"通常对应 AccessKey ID。

Q:短信服务 API 是否支持前端 JS 直接调用或第三方平台对接?

前端 JS 调用:不支持。短信服务 API 没有浏览器端 SDK,纯前端 JavaScript 代码无法直接调用。在前端代码中使用 AccessKey 存在密钥泄露风险,必须通过后端服务集成 SDK 进行调用。

第三方平台对接(如抖音小程序、飞书机器人、深信服 AC 等):使用以下标准参数配置即可,无需特殊接口:

  • Endpoint:dysmsapi.aliyuncs.com

  • 认证:AccessKey ID + AccessKey Secret

  • 必填参数:签名名称(SignName)、模板 CODE(TemplateCode

阿里云不提供代开发服务,业务逻辑的触发与实现需由技术人员自行完成。

Q:国内短信和国际/港澳台短信可以使用同一个 API 接口吗?

不可以。两类短信使用不同的 API 接口,不可混用:

短信类型

API 接口

API 版本

国内短信

SendSms

2017-05-25

国际/港澳台短信

SendMessageToGlobe

2018-05-25

两者的签名、模板及合规要求均不同,混用接口会返回 SMS_CONTENT_CODE_ILLEGALSpecified parameter Region is not valid 等错误。AccessKey 国内与国际通用,无需为两类短信分别创建。

Q:调用短信 API 报错"找不到模板"或"签名非法"如何排查?

请按以下顺序逐项检查:

  1. 账号一致性:确认调用 API 所用的 AccessKey 与控制台中创建模板/签名的阿里云主账号一致(RAM 用户需属于同一主账号)。

  2. 审核状态:登录短信服务控制台,在模板管理签名管理页面确认对应模板/签名状态为"审核通过"。

  3. 参数精确匹配:核对代码中 TemplateCode(格式为 SMS_ 开头)和 SignName 的值与控制台显示完全一致,注意去除首尾多余空格。

  4. 接口区分:确认未混用国际短信接口(SendMessageToGlobe)发送国内短信,两者不兼容。

  5. 实名制报备:若提示"签名非法",检查该签名是否已完成实名制报备,未报备的签名会被运营商拦截。

视频教程