Valid Sender ID Formats:
| Type | Max Length | Examples |
|---|---|---|
| Alphanumeric | 11 characters | SMSPM, MyApp, Shop.com |
| Numeric | 15 digits | 372567890, 1234567890 |
Code Example:
// ❌ Wrong - not approved
{
fromNumber: "My Super Long Company Name"; // Too long!
}
// ✅ Correct - approved in account
{
fromNumber: "SMSPM"; // Must be in your approved list
}
4. "Hash is required"
Error Message:
{
"error": "Hash is required"
}
Cause: Missing hash parameter
Solutions:
✅ Add hash parameter to request
✅ Get hash from User Account → API
✅ Verify hash is complete (no truncation)
✅ Check for typos
5. "Message text is required"
Error Message:
{
"error": "Message text is required"
}
Cause: Empty or missing text parameter
Solutions:
✅ Ensure text parameter is not empty
✅ Check for accidental null/undefined values
✅ Verify text is a string, not an object
Code Example:
// ❌ Wrong
{
text: ""; // Empty!
}
// or
{
text: null; // Null!
}
// ✅ Correct
{
text: "Hello World"; // Has content
}
6. "At least one recipient number is required"
Error Message:
{
"error": "At least one recipient number is required"
}
Cause: Empty toNumber array or missing parameter
Solutions:
✅ Ensure toNumber has at least one phone number
✅ Check array is not empty
✅ Verify variable is defined
Code Example:
// ❌ Wrong
{
toNumber: []; // Empty array!
}
// ✅ Correct (single)
{
toNumber: "37256789045";
}
// ✅ Correct (multiple)
{
toNumber: ["37256789045", "37257788990"];
}
7. HTTP 405 Method Not Allowed
Error: Browser or tool shows "405 Method Not Allowed"
Cause: Using wrong HTTP method
Solutions:
✅ Use GET or POST methods only
✅ For bulk sends, prefer POST
✅ Check your HTTP client configuration
Code Example:
// ❌ Wrong
fetch(url, { method: "PUT" }); // Not supported!
// ✅ Correct
fetch(url, { method: "POST" });
Issues by Symptom
Messages Not Being Delivered
Check:
- ✅ Verify phone number is correct and active
- ✅ Check your account balance (User Account → Dashboard)
- ✅ Confirm sender ID is approved
- ✅ Verify you received success response from API
- ✅ Check if number is on DND (Do Not Disturb) list
- ✅ Wait a few minutes - delivery can take 1-3 minutes
How to Debug:
const response = await sendSMS(data);
console.log("API Response:", JSON.stringify(response, null, 2));
// Success response should look like:
// {
// "messages": [{
// "id": "uuid-here",
// "toNumber": "37256789045",
// "status": "Added to queue"
// }]
// }
Unicode Characters Not Displaying
Symptoms: Emoji or special characters appear as ? or boxes
Solutions:
✅ Ensure UTF-8 encoding in your code
✅ For GET requests, properly URL encode Unicode
✅ Use POST requests for easier Unicode handling
✅ Test with simple emoji first (😊)
Code Example:
// ❌ Wrong (GET with unencoded Unicode)
const url = `https://api.smspm.com?text=Hello 😊&...`;
// ✅ Correct (POST with Unicode)
fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json; charset=utf-8" },
body: JSON.stringify({
text: "Hello 😊 Welcome!",
// ... other params
}),
});
// ✅ Correct (GET with encoded Unicode)
const text = encodeURIComponent("Hello 😊 Welcome!");
const url = `https://api.smspm.com?text=${text}&...`;
Long Messages Getting Cut Off
Symptoms: Only first part of message received
Cause: Message split into multiple parts, but only one sent
Solutions:
✅ API automatically splits messages - you should receive all parts
✅ Verify account has enough balance for all parts
✅ Check if carrier supports concatenated SMS
✅ Contact support if issue persists
Message Splitting:
- Standard: 160 chars → splits at 153 chars per part
- Unicode: 70 chars → splits at 67 chars per part
Example:
// A 350-character message will send as 3 separate SMS
const longMessage = "a".repeat(350); // 350 characters
// API handles splitting automatically
// Part 1: 153 chars
// Part 2: 153 chars
// Part 3: 44 chars
// Total: 3 SMS charged
CORS Errors in Browser
Error: "CORS policy: No 'Access-Control-Allow-Origin' header"
Cause: Making API calls directly from browser
Solutions:
✅ Best: Make calls from your backend server
✅ Never expose credentials in frontend code
✅ Use server-side proxy if needed
Architecture:
Browser → Your Server (API credentials here) → SMSPM API
Example:
// ❌ Wrong - Frontend calling API directly
// Frontend (browser.js)
fetch("https://api.smspm.com", {
method: "POST",
body: JSON.stringify({
hash: "YOUR_HASH", // EXPOSED!
token: "YOUR_TOKEN", // EXPOSED!
}),
});
// ✅ Correct - Backend calling API
// Frontend (browser.js)
fetch("/api/send-sms", {
// Your own server
method: "POST",
body: JSON.stringify({
toNumber: "37256789045",
text: "Hello",
}),
});
// Backend (server.js)
app.post("/api/send-sms", async (req, res) => {
const response = await fetch("https://api.smspm.com", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
hash: process.env.SMSPM_HASH, // Safe!
token: process.env.SMSPM_TOKEN, // Safe!
toNumber: req.body.toNumber,
text: req.body.text,
fromNumber: "SMSPM",
}),
});
const data = await response.json();
res.json(data);
});
Request Timeout
Symptoms: Request takes too long or times out
Solutions:
✅ Check your internet connection
✅ Increase timeout in your HTTP client
✅ Retry with exponential backoff
✅ Use smaller batches (split 100 into 2x50)
Code Example:
async function sendWithRetry(data, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const response = await fetch(apiUrl, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
signal: AbortSignal.timeout(30000), // 30 second timeout
});
return await response.json();
} catch (error) {
if (i === maxRetries - 1) throw error;
// Wait before retry (exponential backoff)
await new Promise((resolve) =>
setTimeout(resolve, Math.pow(2, i) * 1000)
);
}
}
}
Debugging Tips
1. Test with cURL First
# Test basic connectivity
curl -v "https://api.smspm.com?hash=YOUR_HASH&toNumber=37256789045&text=Test&fromNumber=SMSPM&token=YOUR_TOKEN"
2. Check Response Status
const response = await fetch(apiUrl, options);
console.log("Status:", response.status); // Should be 200
console.log("OK:", response.ok); // Should be true
const data = await response.json();
console.log("Data:", data);
if (data.error) {
console.error("Error:", data.error);
}
3. Validate Your Data
function validateSMSRequest(data) {
const errors = [];
if (!data.hash) errors.push("Missing hash");
if (!data.token) errors.push("Missing token");
if (!data.toNumber) errors.push("Missing toNumber");
if (!data.text) errors.push("Missing text");
if (!data.fromNumber) errors.push("Missing fromNumber");
if (data.toNumber) {
const numbers = Array.isArray(data.toNumber)
? data.toNumber
: [data.toNumber];
numbers.forEach((num) => {
const cleaned = num.toString().replace(/\D/g, "");
if (cleaned.length < 5) {
errors.push(`Invalid phone: ${num}`);
}
});
}
return errors;
}
// Usage
const errors = validateSMSRequest(myData);
if (errors.length > 0) {
console.error("Validation errors:", errors);
} else {
sendSMS(myData);
}
4. Log Everything (Development Only!)
console.log("=== SMS API Call ===");
console.log("Endpoint:", apiUrl);
console.log("Method:", "POST");
console.log("Payload:", {
hash: data.hash.substring(0, 8) + "...", // Don't log full credentials
token: "***", // Never log token
toNumber: data.toNumber,
text: data.text,
fromNumber: data.fromNumber,
});
const response = await fetch(apiUrl, options);
console.log("Response Status:", response.status);
const result = await response.json();
console.log("Response Body:", result);
console.log("===================");
Still Having Issues?
Check System Status
Verify the API is operational (rare outages are announced via email)
Gather Debug Information
Before contacting support, collect:
- ✅ Your account hash (first 8 characters only)
- ✅ Example request (with token removed)
- ✅ Complete error message
- ✅ Timestamp of the issue
- ✅ Programming language and HTTP library used
- ✅ What you expected vs what happened
Contact Support
- Email: [email protected]
- Phone: +372 5451 5400 / +447 412 961 801
- Hours: Daily 08:00-20:00 (GMT +2)
Support Email Template:
Subject: API Issue - [Brief Description]
Account Hash: 52248aec... (first 8 chars only)
Problem: [Describe what's not working]
Expected: [What should happen]
Actual: [What's actually happening]
Request Example (token removed):
{
"hash": "52248aec...",
"toNumber": "37256789045",
"text": "Hello",
"fromNumber": "SMSPM"
}
Error Response:
{
"error": "..."
}
Timestamp: 2025-10-16 14:30:00 GMT+2
Environment: Node.js 18, using fetch API
Prevention Checklist
Use this checklist before deploying to production:
- Credentials stored as environment variables
- Phone numbers validated before sending
- Error handling implemented
- Retry logic for network failures
- Rate limiting on your side
- Logging (without exposing credentials)
- Balance monitoring
- Test with approved sender IDs
- Unicode messages tested
- Bulk sending tested with small batch first
- Backend handles API calls (not frontend)
Happy troubleshooting! 🔧
Need more help? Check the Complete API Documentation or Quick Start Guide.