sms compliance

Sent logo
Sent TeamMay 3, 2025 / sms compliance / Article

São Tomé and Príncipe SMS Guide: Send SMS to +239 Numbers via API

Learn how to send SMS to São Tomé and Príncipe (+239). Complete API integration guide with Twilio, Plivo, Sinch examples, E.164 formatting, AGER compliance, pricing, and best practices for ST mobile numbers.

São Tomé and Príncipe SMS Best Practices, Compliance, and Features

Learn how to send SMS messages to São Tomé and Príncipe (country code ST, +239) using this comprehensive API integration guide. Whether you're implementing SMS notifications, OTP authentication, or marketing campaigns, this guide covers everything you need: E.164 phone number formatting (+239XXXXXXX), regulatory compliance requirements under AGER supervision, SMS pricing from major providers (Twilio, Plivo, Sinch, Bird), supported features, sender ID options, content restrictions, and best practices for the São Tomé and Príncipe telecommunications market.

São Tomé and Príncipe SMS Market Overview

Locale name:São Tomé and Príncipe
ISO code:ST
RegionMiddle East & Africa
Mobile country code (MCC)626
Dialing Code+239

Market Conditions: São Tomé and Príncipe's mobile telecommunications sector continues to grow with increasing SMS adoption. The market has limited competition among mobile operators and moderate smartphone penetration. While OTP messaging apps gain popularity in urban areas, SMS remains the most reliable channel for business communications and notifications due to its universal reach and reliability.

For developers working with other African countries, see our guides on sending SMS to Nigeria, Kenya SMS integration, and South Africa SMS APIs.


SMS Features and Capabilities in São Tomé and Príncipe

São Tomé and Príncipe supports basic SMS functionality with some limitations on advanced features. Understanding these specific capabilities and restrictions is essential when implementing SMS communications.

Two-Way SMS Support

São Tomé and Príncipe does not support two-way SMS according to current provider capabilities. Design your SMS strategies around one-way communications only.

Concatenated Messages (Segmented SMS)

Support: Yes, concatenated messages are supported, though availability may vary by sender ID type.

Message length rules: Standard SMS length limits apply – 160 characters for GSM-7 encoding and 70 characters for Unicode messages.

Encoding considerations: Both GSM-7 and UCS-2 encodings are supported, with messages split and rejoined based on the encoding used.

Character Encoding Limits:

EncodingSingle SMSMulti-part SMSBilling Impact
GSM-7160 characters153 characters per segmentEach segment billed separately
UCS-2/Unicode70 characters67 characters per segmentEach segment billed separately

Messages exceeding these limits automatically split into multiple segments, with each segment counting as a separate SMS for billing.

Example: A 200-character message using GSM-7 encoding splits into two segments: the first 153 characters form segment 1, and the remaining 47 characters form segment 2. You'll be billed for 2 SMS messages.

MMS Support

MMS messages are not directly supported in São Tomé and Príncipe. Instead, MMS content automatically converts to SMS with an embedded URL link where recipients can view the multimedia content. This ensures compatibility while still allowing you to share rich media content with your audience.

Recipient Phone Number Compatibility

E.164 Phone Number Format for São Tomé and Príncipe

São Tomé and Príncipe phone numbers must follow the E.164 international format for SMS API integration:

  • Format: +239XXXXXXX (country code +239 followed by 7 digits)
  • Total length: 11 characters including the + symbol
  • Example: +2399912345
  • Always include the country code when sending SMS via API

Valid vs Invalid Examples:

StatusNumberReason
✓ Valid+2399912345Correct E.164 format with country code
✓ Valid+2399987654Proper 7-digit local number
✗ Invalid9912345Missing country code
✗ Invalid+239991234Only 6 digits (needs 7)
✗ Invalid+239991234568 digits (exceeds 7-digit limit)
✗ Invalid002399912345Wrong international prefix format

Number Portability

Number portability is not available in São Tomé and Príncipe. Mobile numbers remain tied to their original carrier, which simplifies message routing but limits consumer flexibility in changing providers.

Sending SMS to Landlines

Sending SMS to landline numbers is not supported in São Tomé and Príncipe. Attempts to send messages to landline numbers result in failed delivery and an error response (400 error code 21614) from the API. These messages will not appear in logs and your account will not be charged for failed attempts.

Identifying Number Types: Most São Tomé and Príncipe mobile numbers start with specific prefixes. Use phone number validation libraries like Google's libphonenumber to programmatically identify mobile vs landline numbers before sending. For comprehensive phone validation guidance, see our E.164 phone format guide.


SMS Compliance Requirements in São Tomé and Príncipe

SMS communications in São Tomé and Príncipe must comply with general telecommunications regulations and data protection laws. While specific SMS marketing regulations are still evolving, follow international best practices and general privacy principles to ensure compliance.

Regulatory Authority: The AGER (Autoridade Geral de Regulação de São Tomé e Príncipe) regulates telecommunications, postal services, water, and electricity sectors. AGER manages spectrum allocation, numbering systems, and telecommunications policies. (Source: AGER official website, verified January 2025)

AGER Contact Information:

  • Website: https://ager.st/
  • Location: São Tomé
  • For complaints or inquiries, visit the AGER website or contact through official government channels.

Explicit Consent Requirements:

  • Obtain clear, explicit consent before sending any marketing messages
  • Document and maintain records of all opt-in confirmations
  • Provide clear information about message frequency and content type
  • Include company identification in consent requests

Best Practices for Consent Collection:

  • Use double opt-in processes for marketing lists
  • Store consent timestamps and collection methods
  • Regularly clean and update consent records
  • Provide clear terms and conditions during opt-in

Sample Consent Language:

English: "By clicking 'Subscribe,' you agree to receive marketing messages from [Company Name] at this phone number. Message frequency varies. Reply STOP to unsubscribe. Message and data rates may apply."

Portuguese: "Ao clicar em 'Subscrever,' você concorda em receber mensagens de marketing de [Company Name] neste número de telefone. A frequência das mensagens varia. Responda STOP para cancelar. Podem aplicar-se taxas de mensagens e dados."

HELP/STOP and Other Commands

While São Tomé and Príncipe doesn't mandate specific keywords, implementing standard opt-out mechanisms is recommended:

  • Include STOP option in marketing messages
  • Support common opt-out keywords (STOP, END, CANCEL, PARAR)
  • Process opt-out requests within 24 hours
  • Support both Portuguese and English commands

Implementation Example:

typescript
function processInboundMessage(message: string, phoneNumber: string): void {
  const normalizedMessage = message.trim().toUpperCase();
  const optOutKeywords = ['STOP', 'END', 'CANCEL', 'PARAR', 'CANCELAR'];

  if (optOutKeywords.includes(normalizedMessage)) {
    // Add to suppression list
    addToOptOutList(phoneNumber);

    // Send confirmation
    sendSMS(phoneNumber, 'You have been unsubscribed. No more messages will be sent.');

    // Log the opt-out
    logOptOut(phoneNumber, new Date());
  }
}

Do Not Call / Do Not Disturb Registries

São Tomé and Príncipe currently does not maintain an official Do Not Call registry. However, you should:

  • Maintain internal opt-out databases
  • Honor all opt-out requests immediately
  • Keep suppression lists updated
  • Regularly clean contact databases

Time Zone Sensitivity

São Tomé and Príncipe observes UTC+0 (GMT – Greenwich Mean Time) year-round with no Daylight Saving Time changes. (Source: TimeAndDate.com, verified January 2025)

Best practices include:

  • Send messages between 8:00 AM and 8:00 PM local time
  • Avoid messaging during religious holidays and national observances
  • Respect weekend quiet hours
  • Only send urgent messages outside these hours

Major Holidays to Avoid:

  • New Year's Day (January 1)
  • Martyrs' Day (February 3)
  • International Women's Day (March 8)
  • Labour Day (May 1)
  • Independence Day (July 12)
  • Armed Forces Day (September 6)
  • Agricultural Reform Day (September 30)
  • National Day (December 21)
  • Christmas Day (December 25)

Timezone Conversion Example:

typescript
import { DateTime } from 'luxon';

function isAcceptableSendTime(recipientTimezone: string = 'UTC'): boolean {
  const recipientTime = DateTime.now().setZone(recipientTimezone);
  const hour = recipientTime.hour;

  // Check if between 8 AM and 8 PM
  return hour >= 8 && hour < 20;
}

// Usage for São Tomé and Príncipe
if (isAcceptableSendTime('UTC')) {
  sendSMS(phoneNumber, message);
}

Sender ID Options for São Tomé and Príncipe SMS

Alphanumeric Sender ID

Operator network capability: Supported with dynamic usage allowed

Registration requirements: No pre-registration required

Sender ID preservation: Sender IDs are generally preserved but may be subject to operator policies

Character Limits and Formatting Rules:

  • Maximum length: 11 characters
  • Allowed characters: A-Z, a-z, 0-9, space
  • Cannot start with a number
  • Case-sensitive (BRAND differs from Brand)
  • No special characters or symbols

Examples:

StatusSender IDReason
✓ ValidYourBrandWithin 11 chars, alphanumeric
✓ ValidCompany123Alphanumeric with numbers
✓ ValidInfoShort and clear
✗ Invalid123CompanyStarts with number
✗ InvalidYour-BrandContains special character (-)
✗ InvalidVeryLongCompanyNameExceeds 11 characters

Best Practices:

  • Use recognizable brand names
  • Keep it short (6-8 characters ideal)
  • Test with local carriers before large campaigns
  • Consider operator-specific requirements

Long Codes

Domestic vs International: International long codes supported; domestic long codes not currently available

Sender ID preservation: Original sender ID typically preserved for international numbers

Provisioning time: Immediate to 24 hours

Use cases: Transactional messages, alerts, and notifications

Acquisition Process:

  1. Contact your SMS provider (Twilio, Plivo, etc.)
  2. Request international long code for São Tomé and Príncipe
  3. Verify provisioning time and costs with provider
  4. Configure sender ID in your application

Short Codes

Support: Not currently supported in São Tomé and Príncipe

Provisioning time: N/A

Use cases: N/A


What Content Restrictions Apply to SMS in São Tomé and Príncipe?

Restricted Industries and Content:

  • Gambling and betting services
  • Adult content and services
  • Unauthorized financial services
  • Political campaign messages without proper authorization
  • Pharmaceutical promotions without proper licensing

Legal Consequences: Violations may result in message blocking, account suspension, or regulatory penalties. Always consult local legal experts for compliance verification.

Rejected Message Examples:

CategoryExampleWhy Rejected
Gambling"Win big at CasinoName! Bet now!"Promotes gambling services
Adult"Hot singles in your area…"Adult content
Unauthorized Finance"Get instant loan without verification"Unlicensed financial services
Political"Vote for Candidate X tomorrow!"Unauthorized political campaigning

Content Filtering

Known Filtering Rules:

  • Messages containing certain keywords may be blocked
  • URLs may be subject to screening
  • High-volume identical messages may be filtered as spam

Common Keywords That Trigger Filtering:

  • Excessive use of "FREE," "WIN," "WINNER"
  • Financial terms: "LOAN," "CREDIT," "DEBT"
  • Urgency triggers: "ACT NOW," "LIMITED TIME"
  • Adult-related terminology

Best Practices to Avoid Filtering:

  • Avoid spam-triggering words
  • Use approved URL shorteners (bit.ly, branded domains)
  • Vary message content for bulk sends (add personalization)
  • Maintain consistent sending patterns
  • Test messages before large campaigns

What Are the Best Practices for Sending SMS in São Tomé and Príncipe?

Messaging Strategy

  • Keep messages under 160 characters when possible
  • Include clear call-to-actions
  • Use personalization thoughtfully
  • Maintain consistent brand voice

Message Template Examples:

OTP/2FA: "Your verification code is 123456. Valid for 10 minutes. Do not share this code."

Transactional: "Your order #12345 has shipped. Track at [URL]. Questions? Reply HELP."

Marketing: "Hi [Name], get 20% off your next purchase with code SAVE20. Valid until [Date]. Shop now: [URL]"

Sending Frequency and Timing

  • Limit to 2-4 messages per week per recipient
  • Respect local holidays and customs
  • Avoid late night/early morning sends (before 8 AM or after 8 PM)
  • Space out bulk campaigns to avoid carrier throttling

Localization

  • Primary languages: Portuguese (official), Forro, Angolar
  • Consider bilingual messages (Portuguese/English) for business communications
  • Use appropriate date and time formats
  • Respect cultural sensitivities

Date and Time Formats:

  • Date format: DD/MM/YYYY (e.g., 15/01/2025)
  • Time format: 24-hour clock (e.g., 14:30)

Portuguese Message Templates:

Transactional: "Seu pedido #12345 foi enviado. Rastreie em [URL]. Dúvidas? Responda AJUDA."

Marketing: "Olá [Nome], ganhe 20% de desconto na sua próxima compra com o código SAVE20. Válido até [Data]. Compre agora: [URL]"

Translation Best Practices:

  • Hire native Portuguese speakers familiar with São Tomé dialect
  • Avoid direct machine translation for marketing content
  • Test messages with local focus groups
  • Consider cultural context and local expressions

Opt-Out Management

  • Process opt-outs within 24 hours
  • Maintain centralized opt-out database
  • Confirm opt-out with acknowledgment message
  • Regular audit of opt-out compliance

Opt-Out Database Schema Example:

typescript
interface OptOutRecord {
  phoneNumber: string;      // E.164 format
  optOutDate: Date;          // When they opted out
  optOutMethod: string;      // 'KEYWORD' | 'WEB' | 'EMAIL' | 'MANUAL'
  campaign: string;          // Which campaign they opted out from
  reason?: string;           // Optional: why they opted out
  confirmed: boolean;        // Confirmation message sent
}

Testing and Monitoring

  • Test across major local carriers before launching campaigns
  • Monitor delivery rates closely (target: >95% delivery rate)
  • Track engagement metrics (opens, clicks, conversions)
  • Generate regular performance reports

Key Performance Indicators (KPIs):

MetricTargetAction if Below Target
Delivery Rate>95%Check number format, carrier issues
Opt-Out Rate<2%Review content, frequency, relevance
Response Rate5-15%Test different CTAs, timing
Error Rate<1%Review API integration, retry logic

Troubleshooting Common Delivery Issues:

IssuePossible CauseSolution
High failure rateInvalid number formatValidate all numbers against E.164
Messages delayedRate limitingImplement queue, reduce send rate
Content blockedFiltered keywordsReview content, test alternative wording
No delivery receiptCarrier issueContact SMS provider support

Monitoring Dashboard Recommendations:

  • Real-time delivery rate graphs
  • Error code frequency charts
  • Geographic distribution maps
  • Time-based sending patterns
  • Cost tracking and budget alerts

São Tomé and Príncipe SMS Pricing by Provider

SMS pricing varies by provider, message volume, and contract terms. Contact providers directly for current rates and volume discounts.

Pricing Factors:

  • Message volume commitments (higher volume = lower per-message cost)
  • Currency conversion rates (USD/EUR to local currency)
  • Sender ID type (alphanumeric vs numeric)
  • Message encoding (GSM-7 vs Unicode)
  • Premium features (delivery reports, two-way messaging)
  • Contract length and commitment terms
ProviderOutbound SMS (USD)NotesVerification
TwilioContact for quotePricing page unavailable (January 2025)Verify with Twilio
PlivoContact for quoteVolume discounts availableVerify directly with provider
SinchContact for quoteEnterprise pricing availableVerify directly with provider
Bird (MessageBird)Contact for quoteCheck for current SDK/APIVerify directly with provider

Important: SMS pricing changes frequently. Always verify current rates with your chosen provider before deploying production campaigns.

Cost Estimation Approach:

  1. Estimate monthly message volume
  2. Request quotes from 3+ providers
  3. Calculate cost per message including all fees
  4. Factor in volume discounts for annual commitments
  5. Include buffer for message segmentation (20-30%)
  6. Add costs for sender ID registration (if applicable)

Example Cost Calculation:

Base scenario: 10,000 messages/month Estimated cost: $0.05-0.10 per message Monthly cost: $500-$1,000 Annual cost with 20% volume discount: $4,800-$9,600

SMS API Integration for São Tomé and Príncipe (+239)

Security Note: Never commit API credentials to version control. Add .env to your .gitignore file:

bash
# Add to .gitignore
.env
.env.local
.env.*.local

Environment Variables Setup:

Create a .env file in your project root:

bash
# Twilio
TWILIO_ACCOUNT_SID=your_account_sid_here
TWILIO_AUTH_TOKEN=your_auth_token_here

# Sinch
SINCH_PROJECT_ID=your_project_id_here
SINCH_KEY_ID=your_key_id_here
SINCH_KEY_SECRET=your_key_secret_here

# MessageBird
MESSAGEBIRD_API_KEY=your_api_key_here

# Plivo
PLIVO_AUTH_ID=your_auth_id_here
PLIVO_AUTH_TOKEN=your_auth_token_here

Twilio SMS API for São Tomé and Príncipe

Twilio provides reliable SMS delivery to São Tomé and Príncipe through their REST API. For more Twilio integration examples, explore our Twilio Node.js tutorials.

typescript
import * as Twilio from 'twilio';

// Initialize client with your credentials
const client = new Twilio(
  process.env.TWILIO_ACCOUNT_SID,
  process.env.TWILIO_AUTH_TOKEN
);

async function sendSMS(to: string, body: string) {
  try {
    // Validate phone number format
    if (!to.startsWith('+239') || to.length !== 12) {
      throw new Error('Invalid São Tomé and Príncipe phone number format');
    }

    // Send message
    const message = await client.messages.create({
      body: body, // Keep under 160 chars for single SMS
      from: 'YourSenderID', // Your approved sender ID
      to: to, // São Tomé and Príncipe number in E.164 format
      statusCallback: 'https://your-domain.com/webhook/delivery-status'
    });

    console.log(`Message sent successfully: ${message.sid}`);
    return message;
  } catch (error) {
    // Handle São Tomé specific error codes
    if (error.code === 21614) {
      console.error('Invalid number format or landline');
    } else if (error.code === 21408) {
      console.error('Rate limit exceeded - implement retry logic');
    } else if (error.code === 21611) {
      console.error('Message content rejected - review content restrictions');
    }

    console.error('Error sending message:', error);
    throw error;
  }
}

Webhook Configuration for Delivery Receipts:

typescript
import express from 'express';
const app = express();

app.post('/webhook/delivery-status', express.urlencoded({ extended: false }), (req, res) => {
  const { MessageSid, MessageStatus, To, ErrorCode } = req.body;

  console.log(`Message ${MessageSid} to ${To}: ${MessageStatus}`);

  if (ErrorCode) {
    console.error(`Delivery failed with error code: ${ErrorCode}`);
  }

  // Update your database with delivery status
  updateDeliveryStatus(MessageSid, MessageStatus);

  res.sendStatus(200);
});

Sinch

Sinch offers direct carrier connections for São Tomé and Príncipe.

typescript
import { SinchClient } from '@sinch/sdk-core';

const sinchClient = new SinchClient({
  projectId: process.env.SINCH_PROJECT_ID,
  keyId: process.env.SINCH_KEY_ID,
  keySecret: process.env.SINCH_KEY_SECRET
});

async function sendSMS(to: string, body: string) {
  try {
    const response = await sinchClient.sms.batches.send({
      sendSMSRequestBody: {
        to: [to], // Must be E.164 format: +239XXXXXXX
        from: 'YourSenderID',
        body: body,
        // Enable delivery reports
        deliveryReport: 'full'
      }
    });

    console.log('Message sent:', response);
    return response;
  } catch (error) {
    console.error('Error:', error);
    throw error;
  }
}

MessageBird

MessageBird provides SMS connectivity to São Tomé and Príncipe with detailed delivery reporting.

Note: MessageBird rebranded to Bird in 2022. The messagebird npm package may be deprecated. Verify current SDK at Bird.com or MessageBird npm package for the latest integration approach.

typescript
import messagebird from 'messagebird';

const client = messagebird(process.env.MESSAGEBIRD_API_KEY);

function sendSMS(to: string, body: string) {
  const params = {
    originator: 'YourSenderID',
    recipients: [to], // E.164 format: +239XXXXXXX
    body: body,
    reportUrl: 'https://your-callback-url.com/delivery-reports'
  };

  client.messages.create(params, (err, response) => {
    if (err) {
      console.error('Error:', err);
      return;
    }
    console.log('Message sent successfully:', response);
  });
}

Plivo

Plivo offers SMS services to São Tomé and Príncipe with high deliverability.

typescript
import plivo from 'plivo';

const client = new plivo.Client(
  process.env.PLIVO_AUTH_ID,
  process.env.PLIVO_AUTH_TOKEN
);

async function sendSMS(to: string, body: string) {
  try {
    const message = await client.messages.create({
      src: 'YourSenderID', // Your sender ID
      dst: to, // Destination number in E.164 format
      text: body,
      // Optional parameters for delivery tracking
      url: 'https://your-callback-url.com/delivery-status',
      method: 'POST'
    });

    console.log('Message sent:', message);
    return message;
  } catch (error) {
    console.error('Error:', error);
    throw error;
  }
}

Production-Ready Implementation with Validation and Retry Logic

typescript
import { Twilio } from 'twilio';
import { parsePhoneNumber } from 'libphonenumber-js';

interface SendResult {
  success: boolean;
  messageId?: string;
  error?: string;
}

class SMSService {
  private client: Twilio.Twilio;
  private maxRetries = 3;
  private retryDelay = 1000; // 1 second

  constructor() {
    this.client = new Twilio(
      process.env.TWILIO_ACCOUNT_SID!,
      process.env.TWILIO_AUTH_TOKEN!
    );
  }

  /**
   * Validate São Tomé and Príncipe phone number
   */
  validatePhoneNumber(phoneNumber: string): boolean {
    try {
      const parsed = parsePhoneNumber(phoneNumber);
      return parsed.country === 'ST' && parsed.isValid();
    } catch {
      return false;
    }
  }

  /**
   * Send SMS with retry logic
   */
  async sendSMS(to: string, body: string, attempt: number = 1): Promise<SendResult> {
    // Validate number
    if (!this.validatePhoneNumber(to)) {
      return {
        success: false,
        error: 'Invalid São Tomé and Príncipe phone number'
      };
    }

    try {
      const message = await this.client.messages.create({
        body,
        from: 'YourSenderID',
        to
      });

      return {
        success: true,
        messageId: message.sid
      };
    } catch (error: any) {
      // Retry on rate limit or temporary errors
      const shouldRetry = error.code === 21408 || error.status >= 500;

      if (shouldRetry && attempt < this.maxRetries) {
        await this.delay(this.retryDelay * attempt);
        return this.sendSMS(to, body, attempt + 1);
      }

      return {
        success: false,
        error: error.message || 'Unknown error'
      };
    }
  }

  private delay(ms: number): Promise<void> {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
}

// Usage
const smsService = new SMSService();
const result = await smsService.sendSMS('+2399912345', 'Hello from São Tomé!');

if (result.success) {
  console.log(`Message sent: ${result.messageId}`);
} else {
  console.error(`Failed to send: ${result.error}`);
}

API Rate Limits and Throughput

  • Default rate limit: 1 message per second per destination
  • Batch sending: Maximum 100 numbers per request
  • Daily sending limits may apply based on account type

Strategies for Large-Scale Sending:

  • Implement queuing system for high-volume campaigns
  • Use batch APIs when available
  • Space out sends to avoid carrier throttling
  • Monitor delivery rates and adjust sending speed

Queue Implementation with Redis:

typescript
import Bull from 'bull';
import Redis from 'ioredis';

// Create queue
const smsQueue = new Bull('sms-queue', {
  redis: {
    host: process.env.REDIS_HOST || 'localhost',
    port: parseInt(process.env.REDIS_PORT || '6379')
  }
});

// Add job to queue
async function queueSMS(to: string, body: string) {
  await smsQueue.add({
    to,
    body,
    timestamp: Date.now()
  }, {
    attempts: 3,
    backoff: {
      type: 'exponential',
      delay: 2000
    }
  });
}

// Process queue
smsQueue.process(async (job) => {
  const { to, body } = job.data;
  const smsService = new SMSService();

  const result = await smsService.sendSMS(to, body);

  if (!result.success) {
    throw new Error(result.error);
  }

  return result;
});

// Monitor queue
smsQueue.on('completed', (job) => {
  console.log(`Job ${job.id} completed`);
});

smsQueue.on('failed', (job, err) => {
  console.error(`Job ${job.id} failed: ${err.message}`);
});

Error Handling and Reporting

Implement comprehensive error handling for production systems:

typescript
interface ErrorStats {
  code: string;
  count: number;
  lastOccurrence: Date;
}

class ErrorMonitor {
  private errors: Map<string, ErrorStats> = new Map();

  recordError(code: string): void {
    const existing = this.errors.get(code);

    if (existing) {
      existing.count++;
      existing.lastOccurrence = new Date();
    } else {
      this.errors.set(code, {
        code,
        count: 1,
        lastOccurrence: new Date()
      });
    }
  }

  getErrorReport(): ErrorStats[] {
    return Array.from(this.errors.values());
  }
}

// Common error codes and retry strategies
const errorHandling = {
  21614: { // Invalid number format
    retry: false,
    action: 'Validate and correct number format'
  },
  21408: { // Rate limit exceeded
    retry: true,
    delay: 5000,
    action: 'Implement exponential backoff'
  },
  21611: { // Message content rejected
    retry: false,
    action: 'Review content against restrictions'
  },
  30003: { // Unreachable destination
    retry: true,
    maxAttempts: 2,
    action: 'Check carrier status'
  }
};

Complete Error Code Reference:

Error CodeMeaningRetry?Action
21614Invalid number format or landlineNoValidate E.164 format
21408Rate limit exceededYesImplement backoff, reduce rate
21611Message content rejectedNoReview content restrictions
21612'To' number not reachableYes (2x)Check carrier, try later
30003Unreachable destinationYes (2x)Verify number is active
30005Unknown destinationNoRemove from list
30008Message delivery failedYes (3x)Check carrier status

Recap and Additional Resources

Key Takeaways

  1. Compliance Priorities:

    • Obtain explicit consent before sending marketing messages
    • Honor opt-out requests within 24 hours
    • Respect sending hours (8 AM – 8 PM UTC+0)
    • Maintain clean contact lists with proper documentation
  2. Technical Considerations:

    • Use E.164 number formatting (+239XXXXXXX)
    • Monitor delivery rates (target >95%)
    • Implement proper error handling with retry logic
    • Follow rate limiting guidelines (1 msg/sec default)
  3. Best Practices:

    • Localize content appropriately (Portuguese primary)
    • Keep messages concise (under 160 characters when possible)
    • Test thoroughly before launching campaigns
    • Maintain proper documentation of consent and opt-outs

Implementation Checklist

Phase 1: Setup (Week 1)

  • Choose SMS provider (Twilio, Plivo, Sinch, or Bird)
  • Set up development environment and API credentials
  • Configure .env file with security best practices
  • Test basic SMS sending functionality

Phase 2: Development (Week 2-3)

  • Implement phone number validation (E.164)
  • Build error handling and retry logic
  • Create opt-out management system
  • Set up delivery status webhooks
  • Implement timezone-aware scheduling

Phase 3: Compliance (Week 3-4)

  • Document consent collection process
  • Build opt-in/opt-out database
  • Implement STOP/HELP keyword handling
  • Review content against restrictions
  • Consult legal experts for compliance verification

Phase 4: Testing (Week 4)

  • Test with small user group (10-20 recipients)
  • Verify delivery across different carriers
  • Test opt-out functionality
  • Monitor error rates and delivery times
  • Validate timezone handling

Phase 5: Production Launch (Week 5)

  • Create monitoring dashboard
  • Set up alerting system (delivery rate drops, error spikes)
  • Develop escalation procedures
  • Train support team on SMS operations
  • Launch with gradual volume ramp-up

Phase 6: Optimization (Ongoing)

  • Analyze engagement metrics weekly
  • A/B test message content and timing
  • Optimize sending frequency
  • Review and update compliance documentation
  • Scale infrastructure based on volume

Common Implementation Questions

Q: Can I use SMS for two-factor authentication in São Tomé and Príncipe?

A: Yes, SMS is commonly used for OTP and 2FA. Use transactional sender IDs and ensure messages are sent immediately upon user request.

Q: How long do messages take to deliver?

A: Typical delivery time is 3-10 seconds. Delays may occur during peak hours or due to carrier issues.

Q: What happens if I send to an invalid number?

A: You'll receive error code 21614, the message won't be delivered, and you won't be charged.

Q: Can I send promotional messages without consent?

A: No. Always obtain explicit consent before sending marketing messages. This is both a legal requirement and a best practice.

Q: How do I handle messages longer than 160 characters?

A: Messages automatically segment. A 200-character message becomes 2 segments, and you're billed for 2 SMS.

Q: What's the best sender ID for my business?

A: Use your brand name (6-11 characters, alphanumeric). Avoid starting with numbers or using special characters.

Next Steps

  1. Technical Implementation:

    • Choose an SMS provider based on your volume and budget
    • Set up development environment with proper security
    • Implement phone validation and error handling
    • Test with small user group before scaling
  2. Compliance:

    • Review local regulations with legal experts
    • Document consent processes thoroughly
    • Set up opt-out handling infrastructure
    • Regular compliance audits
  3. Operations:

    • Create monitoring dashboard with key metrics
    • Set up alerting system for delivery issues
    • Develop escalation procedures for outages
    • Train support team on SMS troubleshooting

Additional Information:

Glossary of Technical Terms

TermDefinition
E.164International phone number format standard (+country code + number)
GSM-77-bit character encoding for SMS (160 chars per message)
UCS-2Unicode encoding for SMS (70 chars per message)
Concatenated SMSMulti-part messages automatically split and rejoined
Sender IDName or number displayed as message sender
Long CodeFull phone number used for sending (e.g., +239XXXXXXX)
Short CodeAbbreviated number for high-volume sending (not supported in ST)
Two-way SMSAbility to send and receive messages (not supported in ST)
MCCMobile Country Code (626 for São Tomé and Príncipe)
UTCCoordinated Universal Time (São Tomé uses UTC+0)
Opt-inUser consent to receive messages
Opt-outUser request to stop receiving messages
Rate LimitMaximum messages per time period
Delivery ReceiptConfirmation of message delivery status

Support and Troubleshooting

Provider Support Contacts:

Regulatory Support:

  • AGER: Visit https://ager.st/ for telecommunications inquiries
  • CNDP: Contact for data protection and privacy questions

Community Resources:

  • GSMA Developer Forums
  • Stack Overflow (tag: sms, twilio, plivo)
  • Provider-specific developer communities

Frequently Asked Questions

How to send SMS messages to Sao Tome and Principe?

Use an SMS API provider like Twilio, Sinch, MessageBird, or Plivo. Provide the recipient's phone number in E.164 format (+239XXXXXXXX) and your approved sender ID. Remember to comply with local regulations and best practices for message content and sending frequency.

What is the SMS market like in Sao Tome and Principe?

Sao Tome and Principe has a growing mobile market with increasing SMS adoption. While OTT apps are gaining traction, SMS remains a reliable communication channel, especially for business uses, due to its wide reach and dependability in a market with limited operator competition.

Why does Sao Tome and Principe not support two-way SMS?

According to current provider capabilities, two-way SMS is not supported. Businesses should therefore design their SMS communication strategies around one-way messaging only.

When should I send SMS messages in Sao Tome and Principe?

Send messages between 8:00 AM and 8:00 PM local time (GMT+0). Avoid sending during religious holidays and weekends, unless it's an urgent message. Respecting local customs and time zones ensures better reception and engagement.

Can I send MMS messages to Sao Tome and Principe?

MMS is not directly supported. MMS content is automatically converted to SMS with a URL link where recipients can view the multimedia. This ensures compatibility while still allowing for rich media sharing.

What are the rules for concatenated SMS in Sao Tome and Principe?

Concatenated messages are supported, with standard length limits of 160 characters for GSM-7 encoding and 70 characters for Unicode. Both GSM-7 and UCS-2 encodings are supported, and message splitting and rejoining depends on the chosen encoding.

How to comply with SMS regulations in Sao Tome and Principe?

Obtain explicit consent before sending marketing messages, honor opt-out requests promptly, respect sending hours, and maintain accurate contact lists. While specific SMS marketing regulations are evolving, following international best practices and privacy principles is crucial.

What sender ID types are available in Sao Tome and Principe?

Alphanumeric sender IDs are supported and don't require pre-registration. International long codes are also supported for transactional messages, alerts, and notifications. Short codes are not currently available.

What content is restricted for SMS in Sao Tome and Principe?

Gambling, adult content, unauthorized financial services, and political campaigns without proper authorization are restricted. Content filtering may block messages with certain keywords or URLs, especially high-volume identical messages.

How to handle opt-outs for SMS in Sao Tome and Principe?

Include a STOP option in marketing messages, support common opt-out keywords (STOP, END, CANCEL), and process requests within 24 hours. While there's no official Do Not Call registry, maintain an internal opt-out database and honor all requests.

What are the best practices for SMS message content in Sao Tome and Principe?

Keep messages concise (under 160 characters), include clear calls-to-action, personalize content thoughtfully, and maintain a consistent brand voice. Consider bilingual messages (Portuguese/English) for business communication.

What are the recommended sending frequency and timing for SMS in Sao Tome and Principe?

Limit messages to 2-4 per week per recipient. Adhere to local holidays and customs. Avoid late-night or early-morning sends, and space out bulk campaigns to prevent carrier throttling and maintain good recipient experience.

What phone number types are compatible with SMS in Sao Tome and Principe?

Mobile numbers are compatible, and number portability is not available. Sending SMS to landlines is not supported and will result in a failed delivery with error code 21614.

What SMS API integration options are available for Sao Tome and Principe?

Twilio, Sinch, MessageBird, and Plivo offer reliable SMS APIs for sending messages to Sao Tome and Principe. These APIs allow for easy integration and provide delivery reports and other helpful features.