sending-sms — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited sending-sms (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
import Sendly from "@sendly/node";
const sendly = new Sendly(process.env.SENDLY_API_KEY!);
const message = await sendly.messages.send({
to: "+15551234567",
text: "Your order has shipped!",
messageType: "transactional",
});All requests require a Bearer token. Store the API key in SENDLY_API_KEY env var.
sk_test_* keys → sandbox mode (no real SMS sent, no credits charged)sk_live_* keys → production (real SMS on verified numbers)Base URL: https://sendly.live/api/v1
curl -X POST https://sendly.live/api/v1/messages \
-H "Authorization: Bearer $SENDLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"to": "+15551234567", "text": "Hello!", "messageType": "transactional"}'Required fields: to (E.164 format), text
Optional fields: messageType (transactional or marketing, defaults to marketing), metadata (object, max 4KB), from (sender ID)
{
"id": "msg_abc123",
"to": "+15551234567",
"text": "Hello!",
"status": "sent",
"segments": 1,
"creditsUsed": 2,
"createdAt": "2026-03-31T10:00:00Z"
}curl -X POST https://sendly.live/api/v1/messages/schedule \
-H "Authorization: Bearer $SENDLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"to": "+15551234567", "text": "Reminder!", "messageType": "transactional", "scheduledAt": "2026-04-01T14:00:00Z"}'Schedule window: 5 minutes to 5 days in the future.
curl -X POST https://sendly.live/api/v1/messages/batch \
-H "Authorization: Bearer $SENDLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"messages": [{"to": "+15551234567", "text": "Hello"}, {"to": "+15559876543", "text": "Hi"}], "messageType": "transactional"}'Up to 10,000 recipients per batch.
curl "https://sendly.live/api/v1/messages?limit=50" \
-H "Authorization: Bearer $SENDLY_API_KEY"Supports limit, offset, status, q (full-text search).
npm install @sendly/nodeimport Sendly from "@sendly/node";
const sendly = new Sendly(process.env.SENDLY_API_KEY!);
const msg = await sendly.messages.send({ to: "+15551234567", text: "Hello!", messageType: "transactional" });
const scheduled = await sendly.messages.schedule({ to: "+15551234567", text: "Later!", messageType: "transactional", scheduledAt: "2026-04-01T14:00:00Z" });
const batch = await sendly.messages.sendBatch({ messages: [{to: "+15551234567", text: "Hi"}], messageType: "transactional" });
const list = await sendly.messages.list({ limit: 50 });
const single = await sendly.messages.get("msg_abc123");Misclassifying marketing as transactional violates TCPA.
Use sk_test_* keys with magic phone numbers:
| Number | Behavior |
|---|---|
| +15005550000 | Always succeeds |
| +15005550001 | Invalid number error |
| +15005550002 | Cannot route error |
| +15005550006 | Carrier rejected |
Messages are automatically threaded into conversations. Use the conversations API for two-way messaging:
const convos = await sendly.conversations.list({ status: "active", limit: 20 });
const replies = await sendly.conversations.suggestReplies("conv_abc123");~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.