在印度市场集成短信API时,最令人头疼的不是发送逻辑本身,而是面对五花八门的错误码不知所措。更棘手的是,消息在API层显示“已提交”,却因下游的DLT过滤、路由不匹配或模板冲突而最终送达失败。本文将系统梳理印度短信API中最常见的错误码,提供实战级的排查方法和解决方案。
**2026年新规提醒**:自2026年1月15日起,TRAI强制要求短信模板中的变量必须使用预定义数据类型标签(如`{numeric}`、`{alphanumeric}`、`{url}`等),未正确标注的模板将直接被运营商拒绝。这是2026年新增的拦截原因,务必注意。
印度短信的错误发生在多个层次,排查时需要逐层定位。
| 错误层级 | 触发阶段 | 典型错误码 | 排查重点 |
| HTTP层 | API请求 | 4xx/5xx | 认证、参数格式、服务端状态 |
| API业务层 | 请求验证 | 101-207等 | 手机号格式、参数完整性 |
| DLT合规层 | 运营商过滤 | 6xx, 4xxx, 5xxx | Entity ID、Header、Template备案 |
| 送达层 | 最终送达 | Webhook回调 | DND拦截、用户手机关机 |
**关键认知**:短信在API层返回“成功”并不代表已送达用户手机——运营商下游过滤是印度市场的常见陷阱。因此,开发者必须建立完整的送达状态追踪机制。
API请求首先会返回HTTP状态码,这是最直观的错误信号。
| HTTP状态码 | 含义 | 排查方法 |
| 400 Bad Request | 请求参数格式错误 | 检查请求体JSON格式、必填字段是否完整、手机号格式是否为`+91xxxxxxxxxx |
| 401 Unauthorized | 认证失败 | 确认API Key是否正确、是否过期、Bearer Token格式是否规范 |
| 403 Forbidden | 无权限 | 检查账户余额是否充足、IP是否被列入白名单、是否在安全设置中禁用了API发送功能 |
| 429 Too Many Requests | 请求频率超限 | 降低并发、实现退避重试、与服务商确认QPS上限 |
| 5xx Server Error | 服务端临时故障 | 实现指数退避重试,通常短暂等待后即可恢复 |
这部分错误码直接反映请求参数的问题,是最容易修复的。
| 错误码 | 含义 | 原因 | 解决方法 |
| 105 | Missing password | API请求缺少认证信息 | 检查API调用是否携带了完整的认证参数 |
| 201 | Invalid username or password | API Key无效或格式错误 | 登录控制台重新生成API Key,确认是否复制完整 |
| 207 | Invalid authentication key | 认证密钥无效 | 检查API Key是否已过期、是否被禁用 |
| 错误码 | 含义 | 原因 | 解决方法 |
| 101 | Missing mobile number | 手机号参数缺失 | 确保API请求中包含`mobile`或`to`参数 |
| 102 | Missing message | 短信内容缺失 | 确保`message`参数非空 |
| 202 | Invalid mobile number | 手机号格式错误 | 必须使用国际格式`91xxxxxxxxxx`(不带`+`号)或`+91xxxxxxxxxx`,不要遗漏国家代码 |
| 203 | Invalid sender ID / DLT Entity ID missing | 发送方ID无效或Entity ID缺失 | 确认Sender ID已在DLT系统备案;使用交易短信时必须携带Entity ID |
| 错误码 | 含义 | 原因 | 解决方法 |
| 208 | IP is blacklisted | 发送IP被加入黑名单 | 联系服务商将IP加入白名单,或更换发送服务器IP |
| 301 | Insufficient balance | 账户余额不足 | 充值后重试 |
| 302 | Expired user account | 账户已过期 | 联系服务商续费 |
| 303 | Banned user account | 账户被封禁 | 检查是否存在违规行为,联系客服申诉 |
| 421 | Service Terminated | 服务已终止 | 联系账户经理了解原因,通常与严重违规或欠费有关 |
| 错误码 | 含义 | 原因 | 解决方法 |
| 311 | Duplicate SMS rejected | 10秒内向同一号码发送相同内容被拒绝 | 这是运营商的防重复机制,旨在防止短信轰炸。首次已送达,重复将被拦截,仅扣费一次。同一号码的相同内容至少间隔10秒以上再发送 |
| 错误码 | 含义 | 原因 | 解决方法 |
| 209 | Default route not found | 默认路由未找到 | 检查API请求中的route参数是否正确配置 |
| 210 | Route could not be determined | 无法确定路由 | 联系技术支持协助排查路由配置 |
| 602 | Current route is disabled | 当前路由已禁用 | 更换其他可用路由,或联系服务商重新启用 |
| 错误码 | 含义 | 原因 | 解决方法 |
| 310 | SMS too long | 短信内容超过允许长度 | 使用分段发送机制,或检查是否为Unicode字符导致单段限制降至70字符 |
| 308 | Campaign name too long | 活动名称超过32字符 | 缩短Campaign name至32字符以内 |
DLT(分布式账本技术)是TRAI强制推行的商业短信监管系统。**当消息被DLT系统拦截时,DLT错误码是最直接的排查线索**。API请求可能在服务商层面成功,但运营商下游过滤时会返回这些DLT错误。
Entity ID是企业在DLT平台的唯一身份标识。
| 错误码 | 含义 | 解决方法 |
| 600 | ENTITY_NOT_FOUND | 确认API请求中携带了正确的Entity ID参数 |
| 601 | ENTITY_NOT_REGISTERED | 企业未在DLT门户完成实体注册。**这是发送短信的前提,必须先完成DLT实体注册** |
| 602 | ENTITY_INACTIVE | Entity ID在平台上处于非活跃状态,联系服务商激活 |
| 603 | ENTITY_BLACKLISTED | 实体被全平台拉黑,通常因严重违规导致,需联系服务商申诉 |
| 604 | INVALID_ENTITY_ID | Entity ID格式错误或缺失标签 |
| 错误码 | 含义 | 解决方法 |
| 620 | HEADER_NOT_FOUND | 确认API请求中使用的Sender ID已在DLT系统备案 |
| 621 | HEADER_INACTIVE | Sender ID处于非活跃状态,需在DLT门户中激活 |
| 622 | HEADER_BLACKLISTED | Sender ID被全平台拉黑,需更换Sender ID |
| 623 | PEID_NOT_MATCHED_WITH_HEADER | Entity ID与Sender ID不匹配,确认使用的是同一企业注册的Header |
**模板错误是目前最常见的拦截原因**。运营商清洗引擎会逐字符比对短信内容与已备案模板,任何差异都会导致拦截。
| 错误码 | 含义 | 解决方法 |
| 630 | TEMPLATE_NOT_FOUND | API请求中未携带Template ID,或Template ID在系统中不存在 |
| 631 | TEMPLATE_INACTIVE | 模板处于非活跃状态,需在DLT门户重新激活 |
| 632 | TEMPLATE_BLACKLISTED | 模板被全平台拉黑,因滥用、用户投诉或违反TRAI指南导致,需重新创建模板 |
| 633 | TEMPLATE_NOT_MATCHED | 短信内容与已备案模板不匹配——**这是最常见的失败原因之一**。检查动态变量格式、标点符号、空格是否与备案模板完全一致 |
| 634 | HEADER_NOT_REGISTERED_FOR_TEMPLATE | Sender ID未绑定到该模板,需确认备案时使用的Header与请求中的Sender ID一致 |
| 635 | TEMPLATE_VARIABLE_EXCEEDED_MAX_LENGTH | 模板变量长度超过配置上限 |
| 637 | INVALID_TEMPLATE_ID | Template ID格式错误或缺失标签 |
| 错误码 | 含义 | 解决方法 |
| 4106/5101-5108 | BLOCKED_BY_DLT | 消息被DLT清洗系统直接拦截,通常为上述Entity/Header/Template问题的汇总 |
| 4107/4001/5000/5001 | DLT_SCRUBBING_TIMEOUT | DLT清洗过程超时,多为运营商侧临时故障,建议重试 |
| 4108/5201-5205 | SENDER_BLOCKED_BY_DLT | 发送方未通过清洗被拦截 |
| 5301-5307/5401-5407 | TEMPLATE_ERROR | 内容模板不匹配或未注册 |
| 7001/7002/7003 | ENTITY_ID_ERROR | Entity不匹配,检查API参数中的Entity ID是否正确 |
- **强制Header后缀**(2025年5月6日生效):所有短信Header必须包含后缀以标识消息类型。
- **变量预标签规则**(2026年1月15日生效):TRAI强制要求短信模板中的每个变量字段必须预标注内容类型标签(如`{numeric}`、`{alphanumeric}`、`{url}`等),模板中的变量必须使用正确的数据类型标签。**未正确标注的模板将被直接拒绝**。
URL编码是导致模板匹配失败的一个常见“隐形杀手”。
当短信网关对消息体进行URL编码时,原始模板中的空格被转换为`+`,`+`号被转换为`%2B`。运营商清洗引擎逐字符比对时,编码后的内容与已备案的原始模板不匹配,导致拦截。
- 检查服务商控制面板是否启用了“自动URL编码”
- 对比发送日志中的实际消息内容和备案模板内容,查找差异
- 使用Postman等工具直接发送原始JSON,排除SDK层自动编码干扰
- **方案一**:在服务商后台禁用消息体自动URL编码
- **方案二**:确保备案模板中已预留编码后的格式占位符
- **方案三**:在API调用前手动对消息体进行编码,保证编码后的内容与备案模板一致
运营商对两类短信的过滤策略完全不同,选错路由将直接导致送达失败。
| 对比维度 | 交易短信 | 促销短信 |
| 发送时间 | 24×7全天候 | 仅限9:00-21:00 |
| DND限制 | 可穿透,送达率更高 | 受DND限制,不可发送给注册DND用户 |
| 发送方ID格式 | 字母组合(如`XYZINFO`) | 数字组合(如`123456`) |
| 用途 | OTP、订单通知、银行提醒 | 营销推广、优惠活动 |
| 路由类型 | transactional | promotional |
**常见错误**:
- 将促销内容通过交易通道发送:违反TRAI规定,可能导致Sender ID被拉黑
- 交易短信使用了促销格式的Sender ID:字母组合与数字组合不匹配,运营商直接拦截
- 两种路由混用:路由参数`type`配置错误
设计重试机制时,常见错误会放大故障而非解决问题。以下是需要重点避开的陷阱:
陷阱一:无视异常类型,盲目全量重试
非临时性错误(如`INVALID_MOBILE_NO`、`INVALID_SENDER_ID`)重复重试毫无意义,只会浪费资源和信用额度。
**✅ 正确做法**:
```python
根据错误类型决定是否重试
RETRYABLE_ERRORS = [408, 429, 500, 502, 503, 504, 4107, 4001, 5000, 5001] 超时/限流/服务端错误
NON_RETRYABLE_ERRORS = [201, 202, 203, 301, 302, 303, 600, 601, 620, 630] 认证/参数/合规错误
if error_code in RETRYABLE_ERRORS:
retry_with_backoff()
elif error_code in NON_RETRYABLE_ERRORS:
log_and_alert() 记录并告警,人工介入
else:
其他错误,谨慎处理
limited_retry()
```
陷阱二:重试风暴——无间隔暴力循环
某短信服务器曾因过载导致请求延迟3秒,客户端在0.5秒内同时发起数万次重试,直接打爆平台,触发了熔断封禁。
**✅ 正确做法**:实现**指数退避**策略,首次重试延迟1秒,第2次2秒,第3次4秒,以此类推,最大延迟不超过60秒。
陷阱三:无上限重试
无限重试会耗尽资源,并可能在故障恢复后造成流量冲击。
**✅ 正确做法**:设置最大重试次数(建议3次),超过后标记失败并进入死信队列。
陷阱四:全队列同步阻塞重试
同步阻塞重试会拖垮整个发送线程池,影响其他业务。
**✅ 正确做法**:使用消息队列异步处理,将失败消息重新投递到延迟队列进行退避重试,发送线程立即释放。
面对复杂的短信发送失败问题,建议采用以下系统化的三步排查流程:
**第一步:核验代码结构**
- 对照官方API文档逐项检查请求参数
- 特别留意参数名称大小写、时间戳格式、签名算法
- 使用Postman或cURL直接调用API,排除SDK层干扰
**第二步:内容规范核查**
- 确认短信模板变量与备案模板完全一致(包括空格、标点、大小写)
- 检查变量长度是否超出限制
- 验证是否为Unicode字符导致分段计费
**第三步:状态码词典对照**
- 建立错误码参考手册
- 对于DLT相关错误码(6xx系列),登录DLT门户查看具体的实体状态和模板审核状态
**第四步(新增):运营商送达层排查**
- 配置Webhook接收送达回执,区分“API成功”和“送达成功”
- 对于长期处于“发送中”状态的记录设置超时重试机制
印度短信API的错误码体系涉及HTTP层、API业务层和DLT合规层三个层次,排查时需逐层定位。总结以下核心建议:
1. **先做DLT合规**:在调用API前,务必完成Entity注册、Header备案和Template审核——这是发送短信的前提
2. **区分错误类型**:根据错误码判断是临时性故障(需重试)还是永久性错误(需人工介入)
3. **实现智能重试**:使用指数退避策略,区分可重试错误和不可重试错误,设置重试上限
4. **路由精准匹配**:交易短信走transactional通道,促销短信走promotional通道,不要混用
5. **警惕URL编码**:确认服务商是否对消息体进行自动编码,确保编码后的内容与备案模板匹配
6. **建立送达追踪**:配置Webhook接收送达回执,区分“API成功”和“送达成功”
掌握这些错误码的排查方法,将大幅提升短信集成的稳定性和开发效率。当遇到不在本文范围内的错误码时,建议联系服务商技术支持获取详细说明。