SMSCode API开发指南:快速集成虚拟号码到你的应用

SMSCode API开发指南:快速集成虚拟号码到你的应用

如果你需要在应用中自动化处理SMS验证码接收,手动操作控制台明显不够高效。SMSCode提供完整的REST API,让你可以将虚拟号码能力直接集成到自己的系统中。

本文从零开始,带你完成SMSCode API的集成,包含可以直接使用的代码示例。

TL;DR: SMSCode API兼容SMS-Activate协议,接入成本极低。核心流程是:获取号码 → 等待验证码 → 标记完成。本文提供Python和Node.js的完整代码示例,30分钟内完成集成。

准备工作

在开始编写代码前,需要完成以下准备:

  1. 注册SMSCode账号并完成邮箱验证
  2. 充值账户余额(API调用需要余额支撑)
  3. 在控制台的”设置”→“API”页面获取你的API密钥
  4. 确认目标服务在SMSCode上可用(查看服务目录

API密钥格式:32位十六进制字符串,例如 a1b2c3d4e5f6...

安全提示:API密钥等同于账号密码权限。不要将其写入代码仓库,应该通过环境变量注入。

API基础

Base URL

https://api.smscode.gg/v1

认证方式

所有请求需要在Header中携带API密钥:

Authorization: Bearer YOUR_API_KEY

或者通过查询参数传入(不推荐,容易出现在日志中):

?api_key=YOUR_API_KEY

请求/响应格式

所有API请求和响应均使用JSON格式。完整的API文档请访问开发者文档

核心工作流

SMS验证码接收的完整流程分三步:

1. 购买号码(获取虚拟号码 + 订单ID)

2. 轮询/等待验证码(最多等待规定时间)

3. 标记订单状态(完成 或 取消)

Python集成示例

以下是一个可以直接使用的Python集成示例:

import requests
import time

class SMSCodeClient:
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://api.smscode.gg/v1"
        self.headers = {"Authorization": f"Bearer {api_key}"}

    def get_number(self, service: str, country: str) -> dict:
        """购买虚拟号码"""
        resp = requests.post(
            f"{self.base_url}/orders",
            headers=self.headers,
            json={"service": service, "country": country}
        )
        resp.raise_for_status()
        return resp.json()["data"]

    def wait_for_sms(self, order_id: str, timeout: int = 120) -> str | None:
        """轮询等待验证码,返回验证码字符串或None"""
        start = time.time()
        while time.time() - start < timeout:
            resp = requests.get(
                f"{self.base_url}/orders/{order_id}",
                headers=self.headers
            )
            data = resp.json()["data"]

            if data["status"] == "completed" and data.get("sms_code"):
                return data["sms_code"]
            elif data["status"] in ["cancelled", "expired"]:
                return None

            time.sleep(5)  # 每5秒轮询一次

        return None

    def cancel_order(self, order_id: str):
        """取消订单(收不到验证码时调用,触发退款)"""
        requests.patch(
            f"{self.base_url}/orders/{order_id}",
            headers=self.headers,
            json={"action": "cancel"}
        )


# 使用示例:注册Google账号
def register_with_google_verification():
    client = SMSCodeClient(api_key="YOUR_API_KEY")

    # 1. 购买印度号码(Google注册推荐)
    order = client.get_number(service="google", country="in")
    phone_number = order["phone"]
    order_id = order["id"]

    print(f"已获取号码: {phone_number}")
    print(f"订单ID: {order_id}")

    # 2. 将phone_number输入到Google注册表单...
    # (在这里添加你的Selenium/Playwright代码)

    # 3. 等待验证码
    code = client.wait_for_sms(order_id, timeout=120)

    if code:
        print(f"收到验证码: {code}")
        # 将验证码填入表单...
    else:
        print("未收到验证码,取消订单")
        client.cancel_order(order_id)

Node.js集成示例

const axios = require('axios');

class SMSCodeClient {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.baseUrl = 'https://api.smscode.gg/v1';
    this.headers = { Authorization: `Bearer ${apiKey}` };
  }

  async getNumber(service, country) {
    const resp = await axios.post(
      `${this.baseUrl}/orders`,
      { service, country },
      { headers: this.headers }
    );
    return resp.data.data;
  }

  async waitForSms(orderId, timeout = 120000) {
    const start = Date.now();
    while (Date.now() - start < timeout) {
      const resp = await axios.get(
        `${this.baseUrl}/orders/${orderId}`,
        { headers: this.headers }
      );
      const data = resp.data.data;

      if (data.status === 'completed' && data.sms_code) {
        return data.sms_code;
      }
      if (['cancelled', 'expired'].includes(data.status)) {
        return null;
      }

      await new Promise(r => setTimeout(r, 5000));
    }
    return null;
  }

  async cancelOrder(orderId) {
    await axios.patch(
      `${this.baseUrl}/orders/${orderId}`,
      { action: 'cancel' },
      { headers: this.headers }
    );
  }
}

// 使用示例
async function main() {
  const client = new SMSCodeClient(process.env.SMSCODE_API_KEY);

  const order = await client.getNumber('whatsapp', 'id'); // 印尼WhatsApp号码
  console.log(`号码: ${order.phone}`);

  // 将号码输入WhatsApp注册页面...

  const code = await client.waitForSms(order.id);
  if (code) {
    console.log(`验证码: ${code}`);
  } else {
    await client.cancelOrder(order.id);
    console.log('未收到验证码,已退款');
  }
}

Webhook实时推送(推荐)

轮询方式简单,但每次请求都有网络开销。对于高并发场景,推荐使用Webhook——验证码到达时,SMSCode主动推送到你指定的URL。

配置Webhook

在控制台的API设置页面,填入你的Webhook URL:

https://your-server.com/smscode-webhook

Webhook接收端(Node.js示例)

const express = require('express');
const crypto = require('crypto');
const app = express();

app.use(express.json());

app.post('/smscode-webhook', (req, res) => {
  // 验证请求来自SMSCode(使用签名验证)
  const signature = req.headers['x-smscode-signature'];
  const payload = JSON.stringify(req.body);
  const expected = crypto
    .createHmac('sha256', process.env.SMSCODE_WEBHOOK_SECRET)
    .update(payload)
    .digest('hex');

  if (signature !== expected) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  const { order_id, phone, sms_code, status } = req.body;

  if (status === 'sms_received' && sms_code) {
    console.log(`订单 ${order_id} 收到验证码: ${sms_code}`);
    // 处理验证码(填入表单、存入数据库等)
    processVerificationCode(order_id, sms_code);
  }

  res.json({ received: true });
});

Webhook方式的优势:

  • 验证码到达后毫秒级响应,无轮询延迟
  • 减少API请求次数,降低成本
  • 适合高并发场景(同时处理数百个号码)

错误处理最佳实践

常见错误码

错误码含义处理方式
400参数错误检查请求参数格式
401API密钥无效检查API密钥是否正确
402余额不足充值后重试
404订单不存在检查订单ID
429请求频率超限降低请求频率,实现退避重试
503号码暂时缺货等待或换其他国家

重试逻辑

import time
import random

def api_call_with_retry(func, max_retries=3):
    for attempt in range(max_retries):
        try:
            return func()
        except requests.exceptions.HTTPError as e:
            if e.response.status_code == 429:
                # 遇到频率限制,指数退避
                wait = (2 ** attempt) + random.random()
                time.sleep(wait)
                continue
            elif e.response.status_code in [500, 503]:
                # 服务器错误,短暂等待后重试
                time.sleep(2 ** attempt)
                continue
            else:
                raise  # 其他错误直接抛出
    raise Exception("超过最大重试次数")

服务代码参考

购买号码时,需要指定服务代码(service参数)。常用服务代码:

平台服务代码
Googlegoogle
WhatsAppwhatsapp
Telegramtelegram
Facebookfacebook
Instagraminstagram
TikToktiktok
Twitter/Xtwitter

完整的服务代码列表,请访问开发者文档或控制台的服务目录。

批量操作优化

对于需要同时处理大量号码的企业用户,需要考虑并发控制:

import asyncio
import aiohttp

async def process_batch(services: list, concurrency: int = 10):
    semaphore = asyncio.Semaphore(concurrency)

    async def process_one(service):
        async with semaphore:
            # 一个号码的完整处理流程
            order = await get_number_async(service)
            code = await wait_for_sms_async(order['id'])
            return {"order": order, "code": code}

    tasks = [process_one(s) for s in services]
    results = await asyncio.gather(*tasks, return_exceptions=True)
    return results

建议的并发限制:

  • 普通账号:最多20个并发请求
  • 企业账号:根据套餐上限,通常可以更高
  • 轮询间隔:至少5秒,避免触发频率限制

迁移自SMS-Activate

已经在使用SMS-Activate API的开发者:SMSCode兼容SMS-Activate协议,迁移通常只需修改一行代码。

SMS-Activate API endpoint:

https://api.sms-activate.org/stubs/handler_api.php

SMSCode兼容endpoint:

https://api.smscode.gg/compat/sms-activate

保持其他代码不变,只修改base URL,即可完成迁移。当然,使用原生SMSCode REST API可以获得更好的功能和错误信息。

查看SMSCode vs SMS-Activate的完整对比了解更多迁移细节。


还有问题?查看完整API文档,或者联系技术支持获取帮助。

FAQ

SMSCode API有免费试用额度吗?

SMSCode按次计费,没有单独的免费试用额度。但注册后可以充值最低金额进行测试,验证码接收失败会自动退款,实际成本风险很低。

API的请求频率限制是多少?

标准账号的API请求限制是每秒10次。如果你需要更高的并发能力,可以联系客服申请企业级配额。对于轮询请求,建议间隔至少5秒,不要无限制地高频轮询。

API密钥泄露了怎么办?

立即在控制台的API设置页面重置API密钥,旧密钥会立即失效。同时检查账号余额和订单历史,确认是否有异常消费。

SMSCode的API支持哪些编程语言?

SMSCode API是标准的REST API,任何支持HTTP请求的语言都可以使用:Python、Node.js、PHP、Java、Go、Ruby等。本文提供了Python和Node.js示例,其他语言的集成方式类似。

如何在测试环境中安全地使用API密钥?

使用环境变量存储API密钥(SMSCODE_API_KEY),不要硬编码到代码中。对于CI/CD环境,使用对应平台的Secrets功能(GitHub Secrets、GitLab CI Variables等)。测试环境建议使用单独的、余额有限的测试账号。

准备试试 SMSCode?

创建账户,两分钟内获取第一个虚拟号码。

立即开始 →