Skip to main content
Manage bulk SMS campaigns that send messages to audience contacts. Related APIs:

Types

// ============================================
// BRANDED TYPES
// ============================================

type SmsProgramId = string & { readonly __brand: 'SmsProgramId' };

// ============================================
// STATUS
// ============================================

type SmsProgramStatus =
  | 'draft'      // Not yet launched, can be edited
  | 'pending'    // Job queued, waiting to start
  | 'sending'    // Currently processing
  | 'completed'  // All messages sent
  | 'cancelled'  // Cancelled by user
  | 'failed';    // Processing failed

// ============================================
// SMS PROGRAM ENTITY
// ============================================

interface SenderIdDetail {
  id: string;        // Sender ID UUID
  senderId: string;  // The actual sender text (e.g. "GoMobile")
  country: string;   // ISO country code (e.g. "MA")
}

interface SmsProgram {
  id: SmsProgramId;
  organizationId: string;
  name: string;
  description: string | null;
  status: SmsProgramStatus;

  // Configuration
  audienceId: string;
  senderId: string;                         // Sender ID UUID (from GET /sender-ids/available)
  resolvedSenderId: SenderIdDetail | null;  // Resolved sender details (null if deleted)
  messageTemplate: string;                  // Template with {{ $contact.* }} placeholders

  // BullMQ job tracking
  jobId: string | null;

  // Progress tracking
  totalContacts: number;

  // Execution timestamps
  startedAt: string | null;
  completedAt: string | null;

  // Error tracking
  errorMessage: string | null;

  // Audit columns
  createdBy: string | null;
  createdAt: string;
  updatedAt: string;
}

interface SmsProgramWithProgress extends SmsProgram {
  progress: {
    sent: number;
    failed: number;
    pending: number;
  };
}

// ============================================
// TEMPLATE SYNTAX
// ============================================

/**
 * Message templates support {{ $contact.* }} placeholders:
 *
 * Contact fields:
 * - {{ $contact.phone }}
 * - {{ $contact.firstName }}
 * - {{ $contact.lastName }}
 * - {{ $contact.fullName }}
 * - {{ $contact.email }}
 * - {{ $contact.address }}
 * - {{ $contact.city }}
 * - {{ $contact.state }}
 * - {{ $contact.zip }}
 * - {{ $contact.occupation }}
 * - {{ $contact.gender }}
 * - {{ $contact.preferredChannel }}
 *
 * Custom attributes:
 * - {{ $contact.customAttributes.fieldName }}
 *
 * Example:
 * "Hello {{ $contact.firstName }}, your balance is {{ $contact.customAttributes.balance }} DH"
 */

API Endpoints

Base path: /sms-programs

Request/Response Types

// ============================================
// QUERY DTOs
// ============================================

interface SmsProgramQueryDto {
  page?: number;        // default: 1
  limit?: number;       // default: 20, max: 100
  search?: string;      // Search in name/description
  sortBy?: string;      // Field to sort by (e.g., 'createdAt', 'name')
  sortOrder?: 'asc' | 'desc';  // default: 'desc'
  status?: SmsProgramStatus;   // Filter by status
}

// ============================================
// CREATE / UPDATE DTOs
// ============================================

interface CreateSmsProgramInput {
  name: string;           // max: 255 chars
  description?: string;
  audienceId: string;     // UUID
  senderId: string;       // UUID (from GET /sender-ids/available)
  messageTemplate: string;
}

interface UpdateSmsProgramInput {
  name?: string;
  description?: string;
  audienceId?: string;
  senderId?: string;      // UUID (from GET /sender-ids/available)
  messageTemplate?: string;
}

// ============================================
// RESPONSE DTOs
// ============================================

interface SmsProgramListResponse {
  data: SmsProgram[];
  meta: {
    page: number;
    limit: number;
    total: number;
    totalPages: number;
    hasNextPage: boolean;
    hasPreviousPage: boolean;
  };
}

interface LaunchSmsProgramResponse {
  id: SmsProgramId;
  status: 'pending';
  totalContacts: number;
  jobId: string;
}

Create a new SMS program

curl -X POST https://api.gomobile.ma/api/sms-programs \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '
{
  "name": "Winter Promo Campaign",
  "description": "Promotional SMS for winter sale",
  "audienceId": "aud_123",
  "senderId": "123e4567-e89b-12d3-a456-426614174000",
  "messageTemplate": "Hello {{ $contact.firstName }}, enjoy 20% off with code WINTER20!"
}
'
Response:
{
  "id": "sms_abc123",
  "organizationId": "org_xyz",
  "name": "Winter Promo Campaign",
  "description": "Promotional SMS for winter sale",
  "status": "draft",
  "audienceId": "aud_123",
  "senderId": "123e4567-e89b-12d3-a456-426614174000",
  "resolvedSenderId": { "id": "123e4567-e89b-12d3-a456-426614174000", "senderId": "GoMobile", "country": "MA" },
  "messageTemplate": "Hello {{ $contact.firstName }}, enjoy 20% off with code WINTER20!",
  "jobId": null,
  "totalContacts": 0,
  "startedAt": null,
  "completedAt": null,
  "errorMessage": null,
  "createdBy": "user_123",
  "createdAt": "2025-01-09T10:00:00.000Z",
  "updatedAt": "2025-01-09T10:00:00.000Z"
}
Error Responses:
CodeErrorDescription
404SenderIdNotFoundErrorSender ID not found
400SenderIdNotActiveErrorSender ID is not active
400SenderIdNotAccessibleErrorSender ID is not available to this organization

List all SMS programs

curl -X GET https://api.gomobile.ma/api/sms-programs?page=1&limit=10&status=draft \
  -H "x-api-key: YOUR_API_KEY"
Response:
{
  "data": [
    {
      "id": "sms_abc123",
      "name": "Winter Promo Campaign",
      "status": "draft",
      ...
    }
  ],
  "meta": {
    "page": 1,
    "limit": 10,
    "total": 25,
    "totalPages": 3,
    "hasNextPage": true,
    "hasPreviousPage": false
  }
}

Get SMS program by ID with progress information

curl -X GET https://api.gomobile.ma/api/sms-programs/sms_abc123 \
  -H "x-api-key: YOUR_API_KEY"
Response:
{
  "id": "sms_abc123",
  "name": "Winter Promo Campaign",
  "status": "sending",
  "totalContacts": 1500,
  "progress": {
    "sent": 850,
    "failed": 12,
    "pending": 638
  },
  ...
}
Error Responses:
CodeDescription
404SMS Program not found

Update an SMS program

Error Responses:
CodeDescription
400Cannot update - status is not draft
404SenderIdNotFoundErrorSender ID not found
400SenderIdNotActiveErrorSender ID is not active
400SenderIdNotAccessibleErrorSender ID is not available to this organization
404SMS Program not found

Delete an SMS program

Error Responses:
CodeDescription
400Cannot delete - status is not draft
404SMS Program not found

Launch an SMS program

Notes:
  • Only programs in draft status can be launched
  • Requires sufficient credits - estimated cost = contacts × 1.887
  • If insufficient credits, returns InsufficientCreditsError
  • On success, status transitions to pending, then sending when job starts
  • Credits are deducted at campaign completion
curl -X POST https://api.gomobile.ma/api/sms-programs/sms_abc123/launch \
  -H "x-api-key: YOUR_API_KEY"
Response:
{
  "id": "sms_abc123",
  "status": "pending",
  "totalContacts": 1500,
  "jobId": "job_xyz789"
}
Error Responses:
CodeErrorDescription
400SmsProgramInvalidStatusErrorStatus is not draft
400SmsProgramNoContactsErrorAudience has no contacts with phone numbers
400InsufficientCreditsErrorNot enough credits to send all messages
400SenderIdDeletedErrorSender ID was deleted since program creation
404SmsProgramNotFoundErrorSMS Program not found

Cancel a running SMS program

Notes:
  • Only programs in pending or sending status can be cancelled
  • Best-effort cancellation - some messages may still be sent
  • Already sent messages are not affected
  • Credits for already sent messages are still charged
Error Responses:
CodeDescription
400Cannot cancel - status is not pending or sending
404SMS Program not found

Billing

SMS programs use the same cost as SMS nodes in call flows: Pre-launch credit check:
  • Before launching, the system calculates: estimatedCost = contactCount × 1.887
  • If balance < estimatedCost, launch is rejected with InsufficientCreditsError
  • Unlike calls (which can go negative due to unpredictable duration), SMS programs require credits upfront
Billing at completion:
  • Credits are deducted at campaign completion based on actual messages sent
  • Transaction type in credit history: sms_charge
  • Failed messages are not charged

Status Lifecycle

draft ──► pending ──► sending ──► completed
  │          │           │
  │          │           └──► failed
  │          │
  │          └──► cancelled

  └──► (deleted)