The following declarations apply to every aliyun CLI invocation in this Skill —
they must be honored before any send / query operation, workflow step, or functional
scenario described later in this document.
Pre-check: Aliyun CLI >= 3.3.3 required
> Run aliyun version to verify the version is >= 3.3.3. If not installed or the version
> is too low, run curl -fsSL https://aliyuncli.alicdn.com/setup.sh | bash to install or
> update.
Pre-check: Aliyun CLI plugin update required
> [MUST] run aliyun configure set --auto-plugin-install true to enable automatic plugin
> installation.
> [MUST] run aliyun plugin update to ensure that any existing plugins on your local
> machine are always up-to-date.
[MUST] Enable AI-Mode — AI-mode is required for Agent Skill execution. Run the
following commands before any CLI invocation:
aliyun configure ai-mode enable
aliyun configure ai-mode set-user-agent --user-agent "AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message"
[MUST] Disable AI-Mode at EVERY exit point — Before delivering the final response
for ANY reason, always disable AI-mode first. This applies to ALL exit paths: workflow
success, workflow failure, error/exception, user cancellation, session end, or any other
scenario where no further CLI commands will be executed. AI-mode is only used for Agent
Skill invocation scenarios and MUST NOT remain enabled after the skill stops running.
aliyun configure ai-mode disable
[MUST] CLI User-Agent — Every aliyun CLI command invocation in this Skill must
include the flag:
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message
This Skill wraps the Alibaba Cloud Short Message Service (SMS) end-to-end on top of the
aliyun CLI, exposing the following capabilities:
(QuerySendStatistics).
single-record detail (QuerySingleSmsQualification) — see
references/sms-qualification.md.
Before executing any send-class operation (send-sms / send-batch-sms), this Skill
must collect these critical parameters first:
--sign-name (signature name)--template-code (template code)--template-param (template variables, when the template contains placeholders)--phone-numbers / --phone-number-json (phone numbers)When the user does not explicitly provide the signature or template, the AI
agent must not guess or fabricate them. Instead it should:
list approved ones from your account for you to pick from."
aliyun dysmsapi query-sms-sign-list ... then aliyun dysmsapi get-sms-sign --sign-name per candidate.aliyun dysmsapi query-sms-template-list ...SignStatus = 1 (approved) and templates with TemplateStatus = 1. Do NOT drop signs based on carrier registration alone — unregistered carriers may still deliver. Instead, surface SignIspRegisterDetailList[*].RegisterResult (per-carrier registration status) as an extra column in the candidate table and let the user decide. Columns: index / code / name / content / SignStatus / per-carrier registration.${xxx} placeholders, ask for each variable's value one by one and assemble them into --template-param JSON.
placeholder numbers like 13800138000 from this document as the actual recipient.
complete send plan and only call send-sms / send-batch-sms after the user gives an
explicit confirmation (e.g. "confirm" / "send")**.
If send-sms returns isv.SMS_SIGN_NAME_ILLEGAL / isv.SMS_TEMPLATE_ILLEGAL, the agent
should proactively offer to "list existing signatures and templates" and, after the user
agrees, call the list APIs instead of retrying blindly.
# macOS
brew install aliyun-cli
# Linux
wget https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-amd64.tgz
tar -xzf aliyun-cli-linux-latest-amd64.tgz && sudo mv aliyun /usr/local/bin/
aliyun version # must be >= 3.3.3
aliyun plugin install --names dysmsapi
The aliyun CLI default credential chain is recommended; it picks credentials in this
priority order: env vars → ~/.aliyun/config.json → ECS RAM role → OIDC Token.
# Recommended for CI/CD: env vars
export ALIBABA_CLOUD_ACCESS_KEY_ID=<your-access-key-id>
export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<your-access-key-secret>
export ALIBABA_CLOUD_REGION_ID=cn-hangzhou
# Verify
aliyun configure get
> Important: Never hard-code AK/SK in code or commands. Always rely on the default
> credential chain. On ECS use a RAM role; in K8s use OIDC.
In the Alibaba Cloud SMS Console: activate the
service, create an approved signature, and create an approved template.
Send SMS:
aliyun dysmsapi send-sms \
--api-version 2017-05-25 \
--phone-numbers "13800138000" \
--sign-name "AliyunDemo" \
--template-code "SMS_123456" \
--template-param '{"code":"123456"}' \
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message \
--read-timeout 3
Batch send (different signatures / template params):
aliyun dysmsapi send-batch-sms \
--api-version 2017-05-25 \
--phone-number-json '["13800138000","13900139000"]' \
--sign-name-json '["SignA","SignB"]' \
--template-code "SMS_123456" \
--template-param-json '[{"code":"111111"},{"code":"222222"}]' \
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message \
--read-timeout 3
Query lists / status / details:
# Approved signatures / templates (use to populate user choices)
aliyun dysmsapi query-sms-sign-list --api-version 2017-05-25 --page-index 1 --page-size 50 --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3
aliyun dysmsapi query-sms-template-list --api-version 2017-05-25 --page-index 1 --page-size 50 --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3
# Single signature / template lookup
aliyun dysmsapi get-sms-sign --api-version 2017-05-25 --sign-name "AliyunDemo" --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3
aliyun dysmsapi get-sms-template --api-version 2017-05-25 --template-code "SMS_123456" --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3
# Per-message delivery details (use BizId for precise lookup)
aliyun dysmsapi query-send-details \
--api-version 2017-05-25 \
--phone-number "13800138000" --send-date "20260326" \
--page-size 10 --current-page 1 \
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3
# Aggregated statistics (--is-globe: 1=domestic, 2=intl/HK-Macao-Taiwan)
aliyun dysmsapi query-send-statistics \
--api-version 2017-05-25 --is-globe 1 \
--start-date "20260301" --end-date "20260326" \
--page-index 1 --page-size 10 \
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3
# Filter by signature name + template type (optional)
aliyun dysmsapi query-send-statistics \
--api-version 2017-05-25 --is-globe 1 \
--start-date "20260301" --end-date "20260326" \
--page-index 1 --page-size 10 \
--sign-name "AliyunDemo" --template-type 0 \
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3
# SMS qualification — list records (full detail in references/sms-qualification.md)
aliyun dysmsapi query-sms-qualification-record \
--api-version 2017-05-25 --page-no 1 --page-size 20 \
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3
# SMS qualification — single detail by GroupId
aliyun dysmsapi query-single-sms-qualification \
--api-version 2017-05-25 --qualification-group-id 10000123 \
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3
> Full filter parameters, response schemas, and state enum mapping for the
> qualification APIs are documented in
> references/sms-qualification.md.
scripts/send_sms.sh automatically applies --api-version, the compliant --user-agent,
and --read-timeout:
# Send (single or comma-separated phones)
./scripts/send_sms.sh send -p "13800138000" -s "AliyunDemo" -t "SMS_123456" -tp '{"code":"123456"}'
# Send with signature/template pre-verification (recommended)
./scripts/send_sms.sh send -p "13800138000" -s "AliyunDemo" -t "SMS_123456" -tp '{"code":"123456"}' --verify
# List & inspect
./scripts/send_sms.sh list-signs
./scripts/send_sms.sh list-templates
./scripts/send_sms.sh query-sign --sign-name "AliyunDemo"
./scripts/send_sms.sh query-template --template-code "SMS_123456"
# Status & statistics
./scripts/send_sms.sh query-status -p "13800138000" --send-date "20260326" --biz-id "xxx^0"
./scripts/send_sms.sh query-statistics --start-date "20260301" --end-date "20260326"
./scripts/send_sms.sh query-statistics --start-date "20260301" --end-date "20260326" --is-globe 2
# Filter by signature name and/or template type
./scripts/send_sms.sh query-statistics --start-date "20260301" --end-date "20260326" --sign-name "AliyunDemo" --template-type 0
| Parameter | Required | Description |
|---|---|---|
| ----------------- | -------- | -------------------------------------------------------- |
| --api-version | Yes | API version, fixed to 2017-05-25 |
| --phone-numbers | Yes | Phone numbers, comma-separated, up to 1000 |
| --sign-name | Yes | SMS signature name |
| --template-code | Yes | SMS template code |
| --template-param | No | Template variables JSON, e.g. '{"code":"123456"}' |
| --out-id | No | External tracking ID |
| --user-agent | Yes | Fixed to AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message |
| --read-timeout | Yes | Read timeout in seconds, recommended value 3 |
| Parameter | Required | Description |
|---|---|---|
| -------------------------- | -------- | ---------------------------------------------------------------------------- |
| --api-version | Yes | API version, fixed to 2017-05-25 |
| --phone-number-json | Yes | Phone numbers JSON array, up to 100, e.g. '["138xxx","139xxx"]' |
| --sign-name-json | Yes | Signature names JSON array, must match the phone count |
| --template-code | Yes | Template code (all phones share the same template) |
| --template-param-json | No | Template variables JSON array, must match the phone count |
| --sms-up-extend-code-json | No | Upstream SMS extension codes JSON array |
| --out-id | No | External tracking ID, less than 256 characters |
| --user-agent | Yes | Fixed to AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message |
| --read-timeout | Yes | Read timeout in seconds, recommended value 3 |
> SendSms vs SendBatchSms: send-sms shares one signature/template across up to 1000
> numbers; send-batch-sms lets each phone use a different signature/template params (up
> to 100 numbers).
| Parameter | Required | Description |
|---|---|---|
| ----------------- | -------- | ------------------------------------------------------------------------------------ |
| --api-version | Yes | API version, fixed to 2017-05-25 |
| --is-globe | Yes | Scope: 1 = domestic; 2 = international / HK-Macao-Taiwan |
| --start-date | Yes | Start date in yyyyMMdd |
| --end-date | Yes | End date in yyyyMMdd |
| --page-index | Yes | Current page, starts from 1 |
| --page-size | Yes | Page size, 1~50 |
| --template-type | No | 0=verify code, 1=notification, 2=marketing(corp), 3=intl/HK-Macao-Taiwan(corp), 7=digital |
| --sign-name | No | Filter by signature name |
| --user-agent | Yes | Fixed to AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message |
| --read-timeout | Yes | Read timeout in seconds, recommended value 3 |
> Response: returns Data.TargetList[] (each entry has SendDate, TotalCount,
> RespondedSuccessCount, RespondedFailCount, NoRespondedCount) and Data.TotalSize.
| Option | Short | Description |
|---|---|---|
| ----------------- | ----- | ------------------------------------------ |
| --phone-numbers | -p | Phone numbers |
| --sign-name | -s | Signature name |
| --template-code | -t | Template code |
| --template-param | -tp | Template variables (JSON) |
| --out-id | -o | External tracking ID |
| --verify | — | Verify signature/template before sending |
| --region | -r | Region ID, defaults to cn-hangzhou |
| --profile | — | Use the given aliyun CLI profile |
{
"BizId": "114814474505895421^0",
"Code": "OK",
"Message": "OK",
"RequestId": "4C3D8B1B-B3D8-5673-B724-1F251799CE9A"
}
| Value | SignStatus / TemplateStatus | Description |
|---|---|---|
| ----- | --------------------------- | ------------------------------------ |
| 0 | Reviewing | SMS cannot be sent for now |
| 1 | Approved | Available for sending |
| 2 | Rejected | Needs revision and resubmission |
| 10 | Cancelled | Sign/template has been cancelled |
| Error code | Description | Suggested action |
|---|---|---|
| -------------------------------- | ------------------------------------ | --------------------------------------------- |
| isv.SMS_SIGNATURE_SCENE_ILLEGAL | Signature/template scene mismatch | Make sure signature and template scenes align |
| isv.SMS_TEMPLATE_ILLEGAL | Template missing or unapproved | Verify the template has been approved |
| isv.SMS_SIGN_NAME_ILLEGAL | Signature missing or unapproved | Verify the signature has been approved |
| isv.MOBILE_NUMBER_ILLEGAL | Bad phone number format | Check the number format |
| isv.AMOUNT_NOT_ENOUGH | Insufficient account balance | Top up the SMS quota |
| isv.BUSINESS_LIMIT_CONTROL | Throttling triggered | Reduce the send rate |
| SignatureNotFound | Signature not found | Create the signature in the console |
| TemplateNotFound | Template not found | Create the template in the console |
> query-send-details ErrCode = Alibaba isv./isp. (above) + carrier receipts (DELIVERED, MOBILE_NOT_ON_SERVICE, MOBILE_SEND_LIMIT, …). Full table + triage: references/sms-error-codes.md.
| Error message | Cause | Resolution |
|---|---|---|
| ---------------------------- | -------------------- | ---------------------------------------------- |
| InvalidAccessKeyId.NotFound | Wrong AccessKey ID | Check the AccessKey ID |
| SignatureDoesNotMatch | Wrong Secret | Check the AccessKey Secret |
| Forbidden.RAM | Insufficient permission | Verify the RAM user has SMS permissions |
AI-Mode enabled; credentials configured.
phone-numbers, sign-name, template-code).If signature or template is missing, ask the user; after consent call
query-sms-sign-list / query-sms-template-list and present approved candidates.
get-sms-sign: require SignStatus=1; also surface SignIspRegisterDetailList[*].RegisterResult to the user as info (unregistered carriers may still deliver — do not block).get-sms-template (TemplateStatus=1).aliyun dysmsapi send-sms (or send-batch-sms for per-recipientpersonalization).
Code=OK only confirms gateway acceptance — return BizId. To report final delivery to the user, always call query-send-details (Scenario 4); never use the send response as proof of delivery.# 1) Pull approved signatures & templates first (so the user can pick)
aliyun dysmsapi query-sms-sign-list --api-version 2017-05-25 --page-index 1 --page-size 50 --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3
aliyun dysmsapi query-sms-template-list --api-version 2017-05-25 --page-index 1 --page-size 50 --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3
# 2) Send (after user confirmation)
aliyun dysmsapi send-sms \
--api-version 2017-05-25 \
--phone-numbers "13800138000" \
--sign-name "YourSign" --template-code "SMS_xxx" \
--template-param '{"code":"123456"}' \
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3
aliyun dysmsapi send-sms \
--api-version 2017-05-25 \
--phone-numbers "13800138000,13900139000,13700137000" \
--sign-name "YourSign" --template-code "SMS_xxx" \
--template-param '{"activity":"Double 11 Sale","discount":"50% OFF"}' \
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3
aliyun dysmsapi send-batch-sms \
--api-version 2017-05-25 \
--phone-number-json '["13800138000","13900139000","13700137000"]' \
--sign-name-json '["BrandA","BrandB","BrandC"]' \
--template-code "SMS_xxx" \
--template-param-json '[{"name":"Alice","code":"111111"},{"name":"Bob","code":"222222"},{"name":"Charlie","code":"333333"}]' \
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3
> Lengths of --phone-number-json, --sign-name-json, and --template-param-json must
> match and correspond one-to-one.
# Per-message delivery (uses BizId returned by send-sms)
aliyun dysmsapi query-send-details \
--api-version 2017-05-25 \
--phone-number "13800138000" --send-date "20260326" --biz-id "xxx^0" \
--page-size 10 --current-page 1 \
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3
# Range-based aggregated statistics (1 row per send-day)
aliyun dysmsapi query-send-statistics \
--api-version 2017-05-25 --is-globe 1 \
--start-date "20260301" --end-date "20260326" \
--page-index 1 --page-size 10 \
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3
> QuerySendDetails vs QuerySendStatistics: query-send-details returns per-message
> records (delivery time, error code) — useful for troubleshooting. query-send-statistics
> returns aggregated daily counts — useful for trend reporting.
aliyun CLI supports multiple profiles. Prefer env vars or RAM roles:
# Option 1: env vars (recommended)
export ALIBABA_CLOUD_ACCESS_KEY_ID=<your-access-key-id>
export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<your-access-key-secret>
# Option 2: profiles (region only; credentials still come from env vars or RAM role)
aliyun configure set --profile prod --region cn-hangzhou
aliyun configure set --profile test --region cn-shanghai
aliyun dysmsapi send-sms --profile prod \
--api-version 2017-05-25 \
--phone-numbers "13800138000" --sign-name "Sign" --template-code "SMS_xxx" \
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3
aliyun plugin install --names dysmsapi.--api-version 2017-05-25 is mandatory.--phone-numbers, not --PhoneNumbers).--read-timeout 3 is required. After a timeout, query the deliveryreceipt before deciding whether to retry.
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-messageis required so the server can identify the caller.
the business layer.
send-sms for verification codes; send-batch-sms is onlyneeded when each recipient requires different signature or template params (≤ 100).
not billed. QPS limit is 5000/s per user.
chain (env vars / ~/.aliyun/config.json / ECS RAM role / OIDC).
after consent fetch query-sms-sign-list / query-sms-template-list (see
"Interactive Parameter Confirmation").
send-sms / send-batch-sms responses only confirm gateway acceptance (Code=OK + BizId); they are NOT proof of delivery. Whenever the user asks "did it arrive?" / "was it delivered?", always call query-send-details (use BizId for precise lookup) and surface SendStatus (1=in-flight, 2=failed, 3=delivered) and ErrCode — never reply based on the send-API response alone.query-send-details ErrCode (Alibaba isv./isp. + carrier receipts); upstream: 101347 / 101346QuerySmsQualificationRecord / QuerySingleSmsQualification共 1 个版本