Tài liệu API SMS để gửi từ mã của riêng bạn

Một API REST nhỏ trên cùng tài khoản, giá cả và số dư như không gian làm việc: gửi một tin nhắn hoặc một loạt lên đến 5,000 số, ước tính chi phí trước, theo dõi từng tin nhắn và nhận các sự kiện giao hàng tại URL webhook của bạn.

URL cơ sở: https://sendsmsonline.cc/api/v1

Bắt đầu nhanh

  1. 1. Tạo một khóa. Trong không gian làm việc, mở API và webhooks. Khóa sẽ được mở sau khi bạn nạp tiền lần đầu tiên; mỗi khóa chỉ hiển thị một lần, vì vậy hãy sao chép hoặc lưu nó dưới dạng tệp văn bản.
  2. 2. Kiểm tra chi phí. POST cùng một nội dung đến /costs để xem người nhận, phân đoạn và tổng chi phí mà không cần gửi.
  3. 3. Gửi. POST nó đến /sends. Câu trả lời sẽ có id gửi; tin nhắn sẽ được gửi ngay lập tức hoặc tại thời điểm send_at.
curl https://sendsmsonline.cc/api/v1/sends \
  -H "Authorization: Bearer $SSO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "recipients": [ { "to": "+447700900461", "fields": { "first_name": "Tom" } }, { "to": "+12015550142", "fields": { "first_name": "Ava" } } ], "text": "Hi {{first_name}}, your table is ready at 7:30.", "name": "Friday bookings", "client_ref": "bookings-1107" }'

Xác thực

Gửi khóa của bạn trong tiêu đề Authorization: Authorization: Bearer sso_live_.... Khóa có 49 ký tự và bắt đầu bằng sso_live_. Tối đa 5 khóa mỗi tài khoản; thu hồi một khóa trong không gian làm việc và nó sẽ ngừng hoạt động ngay lập tức. Bảng giá là công khai và không cần khóa.

Lỗi

Lỗi sử dụng mã trạng thái HTTP và một phần thân JSON với mã ổn định và một câu bạn có thể hiển thị cho một người. Không có gì được tính phí khi một yêu cầu thất bại.

HTTP/1.1 402 Payment Required
{ "error": { "code": "insufficient_credit", "message": "Short by $3.20. Add funds to send.", "total": "8.62480", "credit": "5.42000" } }
TrườngÝ nghĩa
400Yêu cầu cần thay đổi.
401Thiếu, sai hoặc khóa đã bị thu hồi.
402Không đủ số dư cho tổng chi phí.
404Không có lần gửi, tin nhắn, quốc gia hoặc điểm cuối nào như vậy.
409Tin nhắn đã được gửi đi.
429Hơn 240 yêu cầu trong một phút.

Giới hạn

  • 240 yêu cầu mỗi phút cho mỗi khóa, được hiển thị trong X-RateLimit-Limit, X-RateLimit-Remaining và X-RateLimit-Reset (giây unix).
  • 5,000 số điện thoại mỗi yêu cầu, 2,000 ký tự mỗi tin nhắn, 10 phân đoạn mỗi tin nhắn.
  • Tin nhắn được gửi đi với tốc độ tối đa 300 mỗi phút cho mỗi tài khoản.
  • send_at từ 10 phút đến 30 ngày trước.

Giá

GET/api/v1/prices

GET/api/v1/prices/{country}

Giá mỗi tin nhắn (một phân đoạn) cho mỗi quốc gia, tính bằng USD với 5 chữ số thập phân. Không cần khóa.

{ "price": { "country": "GB", "name": "United Kingdom", "dial_code": "+44", "price_usd": "0.00868" }, "updated": "2026-11-07" }

Số dư tài khoản

GET/api/v1/account

{ "account": "SO8K2M4Q7X9TBA", "credit_usd": "41.27660", "currency": "USD" }

Ước tính chi phí

POST/api/v1/costs

Lấy cùng nội dung như một lần gửi và trả về chi phí dự kiến, mà không gửi hoặc tính phí. Văn bản hợp nhất của mỗi người nhận quyết định số phân đoạn, vì vậy tổng chi phí là chính xác.

{
  "recipients": 2, "segments_min": 1, "segments_max": 1, "encoding": "gsm7", "messages_billed": 2,
  "total_usd": "0.01426", "credit_usd": "41.27660", "enough_credit": true,
  "countries": [ { "country": "GB", "recipients": 1, "price_usd": "0.00868", "subtotal_usd": "0.00868" },
                 { "country": "US", "recipients": 1, "price_usd": "0.00558", "subtotal_usd": "0.00558" } ],
  "dropped": [], "too_long": null
}

Tạo một lần gửi

POST/api/v1/sends

Một tin nhắn đến một hoặc nhiều số điện thoại. Số dư cho toàn bộ lần gửi được trừ khi được chấp nhận; tin nhắn thất bại được hoàn lại từng cái một.

TrườngÝ nghĩa
toSố điện thoại ở định dạng quốc tế (+447700900461). Sử dụng cái này hoặc người nhận.
recipientsĐối tượng với to và fields, cho các trường hợp nhất: { "to": "+1...", "fields": { "first_name": "Ava" } }.
textTin nhắn, tối đa 2,000 ký tự. {{field}} được thay thế cho mỗi người nhận; giá trị thiếu sẽ trở thành trống.
send_atThời gian ISO 8601 tùy chọn với độ lệch hoặc Z. Nếu không có, tin nhắn sẽ được gửi ngay lập tức.
nameNhãn tùy chọn hiển thị trong không gian làm việc (80 ký tự).
client_refTham chiếu tùy chọn được trả về trong webhooks (64 ký tự).
opt_outThêm dòng từ chối nhận tin nhắn đã lưu trong Cài đặt vào cuối tin nhắn.
default_countryMã ISO được sử dụng cho các số điện thoại không có mã quốc gia.
HTTP/1.1 201 Created
{
  "send": { "id": "CA7Q29XMAB4DFK", "status": "queued", "source": "api", "recipients": 2, "segments_max": 1,
            "encoding": "gsm7", "cost_usd": "0.01426", "refunded_usd": "0.00000", "client_ref": "bookings-1107",
            "send_at": null, "created_at": "2026-11-07T10:12:03.120Z", "started_at": null, "finished_at": null },
  "dropped": [ { "value": "+4412", "code": "too_short", "message": "Too short" } ]
}

Các số điện thoại không thể gửi được liệt kê trong dropped và không bao giờ bị tính phí. Mã: no_country_code, too_short, too_long, not_a_number, wrong_length, not_covered, duplicate và suppressed (trong danh sách không gửi của bạn).

Lấy hoặc liệt kê các lần gửi

GET/api/v1/sends/{id}

GET/api/v1/sends?limit=25&before={id}

Một lần gửi bao gồm counts cho mỗi trạng thái tin nhắn. Danh sách được sắp xếp từ mới nhất trở đi; chuyển next_before thành before để xem trang tiếp theo. Các lần gửi từ không gian làm việc cũng xuất hiện ở đây, với source: "web".

Tin nhắn

GET/api/v1/sends/{id}/messages?status=failed&limit=100

GET/api/v1/messages/{id}

{ "message": { "id": "MS3D8RW0K2QJ7N", "send_id": "CA7Q29XMAB4DFK", "to": "+447700900461", "country": "GB",
  "segments": 1, "price_usd": "0.00868", "status": "delivered", "reason": null, "reason_text": null,
  "created_at": "2026-11-07T10:12:03.120Z", "sent_at": "2026-11-07T10:12:04.010Z", "done_at": "2026-11-07T10:12:09.400Z" } }

Hủy một lần gửi

POST/api/v1/sends/{id}/cancel

Chỉ các lần gửi đã lên lịch nhưng chưa bắt đầu mới có thể hủy. Toàn bộ chi phí sẽ được hoàn lại vào số dư của bạn và câu trả lời bao gồm refunded_usd.

Webhooks

Đặt một URL https trong không gian làm việc (API và webhooks). Chúng tôi POST một sự kiện khi tin nhắn được gửi thành công hoặc thất bại, cho cả các lần gửi từ API và không gian làm việc. Trả lời với bất kỳ trạng thái 2xx nào trong vòng 10 giây. Các lần gửi thất bại sẽ được thử lại tối đa 7 lần: ngay lập tức, sau đó là 1 phút, 5 phút, 30 phút, 1 giờ, 2 giờ và 3 giờ. Không gian làm việc hiển thị mỗi lần thử với trạng thái và câu trả lời của nó.

POST https://your-server.example/sms-events
X-SSO-Event: message.delivered
X-SSO-Delivery: evt_5a0c9e31d2b7f4a68c
X-SSO-Timestamp: 1794132729
X-SSO-Signature: sha256=8f1c...e42a

{ "id": "evt_5a0c9e31d2b7f4a68c", "event": "message.delivered", "created": "2026-11-07T10:12:09.000Z",
  "data": { "message": { "id": "MS3D8RW0K2QJ7N", "send_id": "CA7Q29XMAB4DFK", "to": "+447700900461", "country": "GB",
  "segments": 1, "price_usd": "0.00868", "status": "delivered", "reason": null, "reason_text": null,
  "client_ref": "bookings-1107", "created_at": "...", "sent_at": "...", "done_at": "..." } } }

Chữ ký là HMAC-SHA256 của timestamp + "." + raw body với khóa bí mật ký của bạn (bắt đầu bằng sso_whk_). Kiểm tra nó trên raw body trước khi phân tích, từ chối các timestamp cũ hơn 5 phút và sử dụng delivery id để bỏ qua các lần lặp lại.

import crypto from "node:crypto";

// rawBody: the request body exactly as received (a string), before JSON.parse
export function verify(rawBody, headers, secret) {
  const ts = headers["x-sso-timestamp"];
  const sig = headers["x-sso-signature"] || "";
  const want = "sha256=" + crypto.createHmac("sha256", secret).update(`${ts}.${rawBody}`).digest("hex");
  const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300;
  return fresh && sig.length === want.length && crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(want));
}

Sự kiện: message.delivered, message.failed và test từ nút Gửi sự kiện thử nghiệm.

Trạng thái và lý do

TrườngÝ nghĩa
queuedĐang chờ rời khỏi hàng đợi của chúng tôi.
sentĐã gửi đến mạng, đang chờ báo cáo giao hàng. Hầu hết các báo cáo đến trong vài phút; một số mạng có thể mất đến 24 giờ.
deliveredMạng đã xác nhận điện thoại nhận được tin nhắn.
failedKhông gửi được. Giá đã được hoàn lại vào số dư của bạn.
canceledKhông gửi vì bạn đã hủy. Đã hoàn tiền.

Lý do thất bại (trường reason):

TrườngÝ nghĩa
network_errorLỗi mạng
absentĐiện thoại tắt hoặc ngoài vùng phủ sóng
not_in_serviceSố không còn hoạt động
blockedBị chặn bởi mạng hoặc người nhận
landlineSố cố định hoặc số không thể nhận SMS
content_filterBị từ chối bởi bộ lọc nội dung của mạng
expiredHết hạn: không có báo cáo trước thời hạn của mạng
canceledĐã hủy trước khi gửi
unknownPhản hồi mạng không xác định

Kiểm tra dịch vụ trên trạng thái trang và thay đổi API trong changelog.

Nhận khóa API của bạn

Tạo tài khoản, nạp tiền một lần và mở API và webhooks trong không gian làm việc. Cùng một khóa hoạt động cho mọi quốc gia.

Tạo tài khoản miễn phí
Tài liệu API SMS: Gửi SMS Hàng Loạt từ Mã của Bạn | SendSMSOnline