๐Ÿ“ฑ SMSGate JS/TS API Client

August 20, 2026 ยท View on GitHub

npm Version License Downloads GitHub Issues GitHub Stars TypeScript

A TypeScript-first client for seamless integration with the SMSGate API. Programmatically send SMS messages through your Android devices with strict typing and modern JavaScript features.

Note: The API doesn't provide CORS headers, so the library cannot be used in a browser environment directly.

๐Ÿ“– Table of Contents

๐Ÿ” Authentication

The SMSGate client supports two authentication methods: Basic Authentication and JWT (JSON Web Token) Authentication. JWT is the recommended approach for production environments due to its enhanced security features and support for scoped permissions.

Basic Authentication

Basic Authentication uses a username and password to access the API. This method is simple but less secure for production use.

When to use:

  • Simple integrations
  • Development and testing
  • Legacy systems

JWT Authentication

JWT Authentication uses bearer tokens with configurable scopes to access the API. This method provides enhanced security and fine-grained access control.

When to use:

  • Production environments
  • Applications requiring scoped permissions
  • Systems with multiple components needing different access levels

โœจ Features

  • TypeScript Ready: Full type definitions out of the box
  • Flexible HTTP Clients: Works with any HTTP library (fetch, axios, node-fetch, etc.)
  • Promise-based API: Async/await ready
  • Webhook Management: Create, read, and delete webhooks
  • Device Management: List and remove devices
  • Health Check: Monitor system status
  • Inbox Export: Export received messages
  • Log Retrieval: Get system logs with time filtering
  • Settings Management: Get, update, and partially update settings
  • Customizable Base URL: Point to different API endpoints
  • Server-Side Focus: Designed for Node.js environments

โš™๏ธ Requirements

  • Node.js v18+
  • npm/yarn/bun package manager

๐Ÿ“ฆ Installation

npm install android-sms-gateway
# or
yarn add android-sms-gateway
# or
bun add android-sms-gateway

๐Ÿš€ Quickstart

Basic Usage

import Client, { MessagePriority } from 'android-sms-gateway';

// First, create a client with Basic Auth to generate a JWT token
const basicAuthClient = new Client(
    process.env.ANDROID_SMS_GATEWAY_LOGIN!,
    process.env.ANDROID_SMS_GATEWAY_PASSWORD!
);

// Generate a JWT token with specific scopes
async function generateJWTToken() {
    try {
        const tokenRequest = {
            scopes: [
                "messages:send",
                "messages:read",
                "devices:list"
            ],
            ttl: 3600 // Token expires in 1 hour
        };
        
        const tokenResponse = await basicAuthClient.generateToken(tokenRequest);
        console.log('JWT Token generated, expires at:', tokenResponse.expires_at);
        return tokenResponse.access_token;
    } catch (error) {
        console.error('Token generation failed:', error);
        throw error;
    }
}

// Initialize client with JWT Authentication
async function initializeJWTClient() {
    const jwtToken = await generateJWTToken();
    
    // Initialize client with JWT token (empty string for login, token for password)
    const jwtClient = new Client(
        "", // Empty string for login when using JWT
        jwtToken // JWT token
    );
    
    return jwtClient;
}

// Send message using JWT Authentication
async function sendSMS() {
    try {
        const jwtClient = await initializeJWTClient();
        
        const message = {
            phoneNumbers: ['+1234567890'],
            message: 'Secure OTP: 123456 ๐Ÿ”',
            priority: MessagePriority.Default
        };
        
        const state = await jwtClient.send(message);
        console.log('Message ID:', state.id);
        
        // Check status after 5 seconds
        setTimeout(async () => {
            const updatedState = await jwtClient.getState(state.id);
            console.log('Message status:', updatedState.state);
        }, 5000);
    } catch (error) {
        console.error('Sending failed:', error);
    }
}

// Revoke a JWT token
async function revokeJWTToken(jti: string) {
    try {
        await basicAuthClient.revokeToken(jti);
        console.log('JWT token revoked successfully');
    } catch (error) {
        console.error('Token revocation failed:', error);
    }
}

sendSMS();

Webhook Management

// Create webhook
const webhook = {
    url: 'https://your-api.com/sms-callback',
    event: WebHookEventType.SmsReceived,
};

api.registerWebhook(webhook)
    .then(created => console.log('Webhook created:', created.id))
    .catch(console.error);

// List webhooks
api.getWebhooks()
    .then(webhooks => console.log('Active webhooks:', webhooks.length));

Device Management

// List devices
api.getDevices()
    .then(devices => console.log('Devices:', devices.map(d => d.name)))
    .catch(console.error);

// Remove a device
api.deleteDevice('device-id')
    .then(() => console.log('Device removed'))
    .catch(console.error);

Health Check

// Check system health
api.getHealth()
    .then(health => {
        console.log('System status:', health.status);
        console.log('Checks:', Object.keys(health.checks).length);
    })
    .catch(console.error);

Inbox Refresh

// Refresh inbox messages (async - server returns 202 Accepted and processes in the background)
const since = new Date('2024-01-01T00:00:00Z');
const until = new Date('2024-01-02T00:00:00Z');

await api.refreshInbox({
    deviceId: 'device-id',
    since,
    until,
    messageTypes: [IncomingMessageType.SMS, IncomingMessageType.MMS],
    webhookDelivery: WebhookDelivery.Batch, // deliver webhooks for refreshed messages as ordered batches
});

Log Retrieval

// Get logs
const from = new Date('2024-01-01T00:00:00Z');
const to = new Date('2024-01-02T00:00:00Z');

api.getLogs(from, to)
    .then(logs => console.log('Logs retrieved:', logs.length))
    .catch(console.error);

Settings Management

// Get settings
api.getSettings()
    .then(settings => console.log('Settings:', settings))
    .catch(console.error);

// Update settings
const newSettings = {
    messages: { limitPeriod: 'PerDay', limitValue: 100 },
    webhooks: { internetRequired: true, retryCount: 3 },
};

api.updateSettings(newSettings)
    .then(() => console.log('Settings updated'))
    .catch(console.error);

// Partially update settings
const partialSettings = {
    messages: { limitValue: 200 },
};

api.patchSettings(partialSettings)
    .then(() => console.log('Settings partially updated'))
    .catch(console.error);

๐Ÿค– Client Guide

Client Configuration

The Client class accepts the following constructor arguments:

ArgumentDescriptionDefault
loginUsername or empty stringRequired
passwordPassword or JWT tokenRequired
httpClientHTTP client implementationfetch
baseUrlAPI base URL"https://api.sms-gate.app/3rdparty/v1"

Authentication Configuration

Basic Authentication:

const api = new Client(
    process.env.ANDROID_SMS_GATEWAY_LOGIN!,  // Username
    process.env.ANDROID_SMS_GATEWAY_PASSWORD!  // Password
);

JWT Authentication:

const api = new Client(
    "",  // Empty string for login when using JWT
    jwtToken  // JWT token
);

The client automatically detects which authentication method to use based on the login parameter:

  • If login is a non-empty string: Uses Basic Authentication
  • If login is an empty string: Uses JWT Authentication with the provided token

Core Methods

MethodDescriptionReturns
Messages
send(message: Message, options?: { skipPhoneValidation?: boolean })Send SMS messagePromise<MessageState>
getState(messageId: string)Check message statusPromise<MessageState>
Webhooks
getWebhooks()List registered webhooksPromise<WebHook[]>
registerWebhook(request: RegisterWebHookRequest)Register new webhookPromise<WebHook>
deleteWebhook(webhookId: string)Remove webhookPromise<void>
Devices
getDevices()List registered devicesPromise<Device[]>
deleteDevice(deviceId: string)Remove devicePromise<void>
Health
getHealth()Check system healthPromise<HealthResponse>
Inbox
refreshInbox(request: InboxRefreshRequest)Refresh inbox messages (async, 202 Accepted)Promise<void>
Logs
getLogs(from?: Date, to?: Date)Get logs within time rangePromise<LogEntry[]>
Settings
getSettings()Get settingsPromise<DeviceSettings>
updateSettings(settings: DeviceSettings)Update settingsPromise<void>
patchSettings(settings: Partial<DeviceSettings>)Partially update settingsPromise<void>
JWT Token Management
generateToken(request: TokenRequest)Generate new JWT tokenPromise<TokenResponse>
revokeToken(jti: string)Revoke JWT token by IDPromise<void>

Type Definitions

/**
 * The fields common to all SMS message variants.
 */
interface MessageCommon {
    /**
     * The ID of the message, generated if not provided.
     * @default null
     */
    id?: string | null;
    /**
     * The optional device ID for explicit device selection.
     * @default null
     */
    deviceId?: string | null;
    /**
     * Whether the message content is encrypted.
     * @default false
     */
    isEncrypted?: boolean;
    /**
     * The time-to-live (TTL) of the message in seconds.
     * Conflicts with `validUntil`.
     * @default null
     */
    ttl?: number | null;
    /**
     * The phone numbers to send the message to.
     */
    phoneNumbers: string[];
    /**
     * The SIM number to send the message from.
     * @default null
     */
    simNumber?: number | null;
    /**
     * Whether to include a delivery report for the message.
     * @default true
     */
    withDeliveryReport?: boolean | null;
    /**
     * The message priority, -128..127 (default 0).
     * Values > 99 bypass sending limits and delays.
     * @default 0
     */
    priority?: number;
    /**
     * Valid until (RFC3339 date-time). Conflicts with `ttl`.
     * @default null
     */
    validUntil?: Date | null;
    /**
     * Schedule delivery at; must be in the future and <= `validUntil`.
     * @default null
     */
    scheduleAt?: Date | null;
}

interface TextMessagePayload {
    text: string;
}

interface DataMessagePayload {
    data: string;
    port: number;
}

/**
 * Represents an SMS message to send.
 * Exactly one of `message`, `textMessage`, or `dataMessage` must be provided;
 * this constraint is enforced by the server at runtime.
 */
interface Message extends MessageCommon {
    /**
     * The message content.
     * @deprecated Use textMessage
     */
    message: string;
    /**
     * The text message payload.
     * Must not be provided together with `message` or `dataMessage`.
     */
    textMessage?: TextMessagePayload;
    /**
     * The data message payload.
     * Must not be provided together with `message` or `textMessage`.
     */
    dataMessage?: DataMessagePayload;
}

/**
 * Message priority constants.
 */
const MessagePriority = {
    Minimum: -128,
    Default: 0,
    BypassThreshold: 100,
    Maximum: 127,
} as const;

interface MessageState {
    id: string;
    state: ProcessState;
    recipients: RecipientState[];
}

interface WebHook {
    id: string;
    event: WebHookEventType;
    url: string;
    deviceId: string;
}

interface Device {
    id: string;
    name: string;
    createdAt: string;
    lastSeen: string;
    updatedAt: string;
    deletedAt?: string | null;
}

interface DeviceSettings {
    messages?: SettingsMessages;
    webhooks?: SettingsWebhooks;
    gateway?: SettingsGateway;
    encryption?: SettingsEncryption;
    logs?: SettingsLogs;
    ping?: SettingsPing;
}

interface HealthResponse {
    status: HealthStatus;
    version: string;
    releaseId: number;
    checks: { [checkName: string]: HealthCheck };
}

interface LogEntry {
    id: number;
    createdAt: string;
    module: string;
    priority: LogEntryPriority;
    message: string;
    context?: Record<string, string>;
}

interface MessagesExportRequest {
    deviceId: string;
    since: Date;
    until: Date;
}

interface InboxRefreshRequest {
    deviceId?: string;
    since: Date;
    until: Date;
    messageTypes?: IncomingMessageType[];
    webhookDelivery?: WebhookDelivery;
}

enum IncomingMessageType {
    SMS = 'SMS',
    DATA_SMS = 'DATA_SMS',
    MMS = 'MMS',
    MMS_DOWNLOADED = 'MMS_DOWNLOADED',
}

enum WebhookDelivery {
    Disabled = 'Disabled',
    Individual = 'Individual',
    Batch = 'Batch',
}

// JWT Authentication Types

interface TokenRequest {
    /**
     * The scopes to include in the token.
     */
    scopes: string[];

    /**
     * The time-to-live (TTL) of the token in seconds.
     */
    ttl?: number;
}

interface TokenResponse {
    /**
     * The JWT access token.
     */
    access_token: string;

    /**
     * The type of the token.
     */
    token_type: string;

    /**
     * The unique identifier of the token.
     */
    id: string;

    /**
     * The expiration time of the token.
     */
    expires_at: string;
}

For more details, see the domain.ts.

๐ŸŒ HTTP Clients

The library comes with fetch-based built-in HTTP client. You can provide your own implementation of the HttpClient interface:

interface HttpClient {
    get<T>(url: string, headers?: Record<string, string>): Promise<T>;
    post<T>(url: string, body: any, headers?: Record<string, string>): Promise<T>;
    put<T>(url: string, body: any, headers?: Record<string, string>): Promise<T>;
    patch<T>(url: string, body: any, headers?: Record<string, string>): Promise<T>;
    delete<T>(url: string, headers?: Record<string, string>): Promise<T>;
}

๐Ÿ”’ Security Notes

โš ๏ธ Important Security Practices

  • Always store credentials in environment variables
  • Never expose credentials in client-side code
  • Use HTTPS for all production communications
  • Rotate passwords regularly
  • Use strong, unique passwords
  • Use appropriate TTL values based on your security requirements
  • Apply the principle of least privilege
  • Implement proper token revocation workflows

๐Ÿ“š API Reference

For complete API documentation including all available methods, request/response schemas, and error codes, visit: ๐Ÿ“˜ Official API Documentation

๐Ÿ‘ฅ Contributing

We welcome contributions! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

Development Setup

git clone https://github.com/android-sms-gateway/client-ts.git
cd client-ts
bun install
bun run build
bun test

๐Ÿ“„ License

Distributed under the Apache 2.0 License. See LICENSE for more information.


Note: Android is a trademark of Google LLC. This project is not affiliated with or endorsed by Google.