devriyad/giosms

Official PHP SDK for GioSMS — Send SMS easily from any PHP or Laravel application.

Maintainers

Package info

github.com/riyadMunauwar/giosms

Homepage

Issues

pkg:composer/devriyad/giosms

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 0

v1.0.1 2026-02-14 14:39 UTC

This package is auto-updated.

Last update: 2026-03-14 14:51:27 UTC


README

Latest Version on Packagist PHP Version License

The official PHP SDK for GioSMS — a fast, reliable SMS gateway for Bangladesh. Works with Laravel 9+ (zero config, auto-discovery) and any standalone PHP 8.1+ project.

Table of Contents

Requirements

  • PHP 8.1 or higher
  • Guzzle 7.x (installed automatically via Composer)
  • A GioSMS account and API token from api.giosms.com

Installation

composer require devriyad/giosms

That's it. Guzzle is pulled in automatically if you don't already have it.

Setup — Laravel

Zero config. The service provider and facade are auto-discovered. No need to edit config/app.php.

Step 1: Add credentials to .env

GIOSMS_TOKEN=your-api-token-here
GIOSMS_SENDER_ID=MyBrand
# GIOSMS_SSL_VERIFY=false  # uncomment for local dev without SSL
Variable Required Description
GIOSMS_TOKEN Yes Your API bearer token from the GioSMS dashboard
GIOSMS_SENDER_ID No Default sender ID (max 16 chars). Can be overridden per request.
GIOSMS_BASE_URL No API base URL. Default: https://api.giosms.com/api/v1
GIOSMS_TIMEOUT No Request timeout in seconds. Default: 30
GIOSMS_SSL_VERIFY No SSL certificate verification. Default: true. Set false for local dev.

Step 2 (Optional): Publish the config file

php artisan vendor:publish --tag=giosms-config

This creates config/giosms.php if you need to customize anything beyond .env variables.

Step 3: Start sending

use GioSMS\Facades\GioSMS;

GioSMS::send([
    'to'      => '8801712345678',
    'message' => 'Hello from GioSMS!',
]);

Setup — Standalone PHP (Without Laravel)

For any PHP project that doesn't use Laravel — plain PHP, Symfony, CodeIgniter, Slim, etc.

Option A: Pass config directly

<?php

require __DIR__ . '/vendor/autoload.php';

use GioSMS\GioSMS;

$sms = new GioSMS([
    'token'     => 'your-api-token-here',
    'sender_id' => 'MyBrand',    // optional default sender ID
    'timeout'   => 30,           // optional, seconds (default: 30)
    // 'ssl_verify' => false,    // uncomment for local dev without SSL
]);

// Send an SMS
$result = $sms->send([
    'to'      => '8801712345678',
    'message' => 'Hello from GioSMS!',
]);

print_r($result);

Option B: Use a .env file (recommended for production)

If you want to keep secrets out of your code, use the popular vlucas/phpdotenv package:

composer require vlucas/phpdotenv

Create a .env file in your project root:

GIOSMS_TOKEN=your-api-token-here
GIOSMS_SENDER_ID=MyBrand

Then load it in your code:

<?php

require __DIR__ . '/vendor/autoload.php';

use Dotenv\Dotenv;
use GioSMS\GioSMS;

// Load .env file
$dotenv = Dotenv::createImmutable(__DIR__);
$dotenv->load();

$sms = new GioSMS([
    'token'     => $_ENV['GIOSMS_TOKEN'],
    'sender_id' => $_ENV['GIOSMS_SENDER_ID'] ?? null,
]);

$result = $sms->send([
    'to'      => '8801712345678',
    'message' => 'Hello from GioSMS!',
]);

print_r($result);

Note: Add .env to your .gitignore so your API token is never committed to version control.

Constructor Parameters

Key Type Required Default Description
token string Yes Your GioSMS API bearer token
sender_id string No null Default sender ID. Can be overridden per request.
base_url string No https://api.giosms.com/api/v1 API base URL
timeout int No 30 HTTP request timeout in seconds
ssl_verify bool No true SSL certificate verification. Set false for local dev without SSL.

Usage

All examples below use the Laravel Facade syntax. For standalone PHP, replace GioSMS::method(...) with $sms->method(...) where $sms is your new GioSMS([...]) instance.

Send Single SMS

use GioSMS\Facades\GioSMS;

$result = GioSMS::send([
    'to'        => '8801712345678',
    'message'   => 'Your order has been shipped!',
    'sender_id' => 'ShopName',      // optional, overrides default
    'type'      => 'transactional', // optional, defaults to 'transactional'
]);

echo $result['data']['message_id']; // "msg_abc123def456"
echo $result['data']['cost'];       // 0.25

Parameters

Key Type Required Description
to string Yes Phone number with country code (e.g. 8801712345678)
message string Yes Message body. Max 1000 characters.
sender_id string No Override default sender ID. Max 16 characters.
type string No otp, transactional, or promotional. Default: transactional

Send OTP (High Priority)

OTP messages are processed in the highest priority queue for the fastest possible delivery.

$result = GioSMS::otp([
    'to'      => '8801712345678',
    'message' => 'Your verification code is 9182. Valid for 5 minutes.',
]);

The type is automatically set to otp — you don't need to specify it.

Send Bulk SMS

Send the same message to multiple phone numbers at once. Pass to as an array — the SDK handles the comma-separated conversion.

$result = GioSMS::bulk([
    'to' => [
        '8801712345678',
        '8801812345678',
        '8801912345678',
    ],
    'message'   => 'Flash sale! 50% off today only.',
    'sender_id' => 'MyBrand',
    'type'      => 'promotional', // optional, defaults to 'promotional'
]);

// Track this batch
echo $result['data']['batch_id'];          // "batch_m1abc_7kR4xWz9pQ2n"
echo $result['data']['total_recipients'];  // 3
echo $result['data']['total_cost_reserved']; // 0.75

Send to Contacts

Send to contacts stored in your GioSMS account by their IDs.

$result = GioSMS::toContacts([
    'contact_ids' => [1, 2, 3, 45, 67],
    'message'     => 'Hello from GioSMS!',
    'sender_id'   => 'MyBrand',
    'type'        => 'transactional', // optional, defaults to 'transactional'
]);

Send to Groups

Send to all contacts in one or more groups. Duplicate phone numbers across groups are automatically deduplicated by the API.

// With a message body
$result = GioSMS::toGroups([
    'group_ids' => [1, 2],
    'message'   => 'Monthly newsletter is here!',
]);

// Or with a pre-approved template
$result = GioSMS::toGroups([
    'group_ids'   => [1, 2],
    'template_id' => 5,
    'sender_id'   => 'MyBrand',
]);

Provide either message or template_id, not both.

Check Delivery Status

$result = GioSMS::status([
    'message_id' => 'msg_abc123def456',
]);

echo $result['data']['status'];       // "delivered"
echo $result['data']['delivered_at'];  // "2026-02-10T12:00:03+00:00"

Status flow: queuedsubmitteddelivered or failed

Check Balance & Cost Estimate

// Check balance
$result = GioSMS::balance();

echo $result['data']['balance'];            // 1250.50
echo $result['data']['currency'];           // "BDT"
echo $result['data']['rates']['masking'];   // 0.50
echo $result['data']['rates']['non_masking']; // 0.25

// Estimate cost for a specific message
$result = GioSMS::balance([
    'message' => 'Hello World',
]);

echo $result['data']['estimate']['sms_count'];              // 1
echo $result['data']['estimate']['encoding'];               // "gsm"
echo $result['data']['estimate']['cost_non_masking'];       // 0.25
echo $result['data']['estimate']['can_send_count_masking']; // 2501

Batch Tracking

// Get report for a specific batch
$result = GioSMS::batch([
    'batch_id' => 'batch_m1abc_7kR4xWz9pQ2n',
]);

echo $result['data']['status'];       // "completed" or "processing"
echo $result['data']['total_sent'];   // 4900
echo $result['data']['total_failed']; // 88

// If still processing, live_stats will be present:
// $result['data']['live_stats']['delivered']
// $result['data']['live_stats']['pending']

// List all active (in-progress) batches
$result = GioSMS::activeBatches();

echo $result['data']['count']; // number of active batches

// Get batch history (most recent first)
$result = GioSMS::batchHistory();                  // default: 20 records
$result = GioSMS::batchHistory(['limit' => 50]);   // up to 100

Health Check

Check if the GioSMS API is up. This endpoint requires no authentication.

$result = GioSMS::health();

echo $result['status'];  // "ok"
echo $result['version']; // "v1"

Error Handling

The SDK throws specific exceptions for each error type. All exceptions extend GioSMSException, so you can catch them broadly or specifically.

use GioSMS\Facades\GioSMS;
use GioSMS\Exceptions\AuthenticationException;
use GioSMS\Exceptions\InsufficientBalanceException;
use GioSMS\Exceptions\ValidationException;
use GioSMS\Exceptions\RateLimitException;
use GioSMS\Exceptions\GioSMSException;

try {
    $result = GioSMS::send([
        'to'      => '8801712345678',
        'message' => 'Hello!',
    ]);
} catch (AuthenticationException $e) {
    // 401 — Your API token is invalid or missing
    // Fix: Check GIOSMS_TOKEN in your .env
} catch (InsufficientBalanceException $e) {
    // 402 — Not enough balance to send this message
    // Fix: Top up your GioSMS account
} catch (ValidationException $e) {
    // 400/422 — Invalid request parameters
    // Fix: Check required fields (to, message, sender_id)
} catch (RateLimitException $e) {
    // 429 — Too many requests
    // Fix: Slow down or use bulk() for multiple numbers
} catch (GioSMSException $e) {
    // Catch-all for any other API/network error (404, 500, timeouts, etc.)
    echo $e->getMessage(); // Human-readable error from the API
    echo $e->getCode();    // HTTP status code
}

Standalone PHP — same approach:

use GioSMS\GioSMS;
use GioSMS\Exceptions\GioSMSException;

$sms = new GioSMS(['token' => 'your-token', 'sender_id' => 'MyBrand']);

try {
    $sms->send([
        'to'      => '8801712345678',
        'message' => 'Hello!',
    ]);
} catch (GioSMSException $e) {
    echo "SMS failed: " . $e->getMessage();
}

Laravel Dependency Injection

Instead of using the Facade, you can type-hint GioSMS anywhere Laravel resolves dependencies — controllers, jobs, commands, etc.

use GioSMS\GioSMS;
use Illuminate\Http\Request;

class OrderController extends Controller
{
    public function store(Request $request, GioSMS $sms): JsonResponse
    {
        $order = Order::create($request->validated());

        $sms->send([
            'to'      => $order->phone,
            'message' => "Order #{$order->id} confirmed! Total: ৳{$order->total}",
        ]);

        return response()->json($order, 201);
    }
}

In a queued job:

use GioSMS\GioSMS;

class SendOrderConfirmation implements ShouldQueue
{
    public function __construct(
        private Order $order,
    ) {}

    public function handle(GioSMS $sms): void
    {
        $sms->send([
            'to'      => $this->order->phone,
            'message' => "Order #{$this->order->id} has been shipped!",
            'type'    => 'transactional',
        ]);
    }
}

Reference

All Methods at a Glance

Method Description Returns
send(array $params) Send single SMS Message data with message_id
otp(array $params) Send OTP (high priority) Message data with message_id
bulk(array $params) Send to multiple numbers Batch data with batch_id
toContacts(array $params) Send to contact IDs Batch data with batch_id
toGroups(array $params) Send to group IDs Batch data with batch_id
status(array $params) Get delivery status Status data
balance(array $params) Check balance / estimate cost Balance and rates data
batch(array $params) Get batch report Batch stats with live progress
activeBatches() List active batches Array of active batches
batchHistory(array $params) Get batch history Array of past batches
health() API health check Status and version

SMS Types & Priority

Type Value Queue Priority Best For
OTP otp 🔴 Highest One-time passwords, verification codes
Transactional transactional 🟡 Medium Order confirmations, alerts, notifications
Promotional promotional 🟢 Low Marketing campaigns, offers, newsletters

Default type is transactional for send(), otp(), and toContacts(), and promotional for bulk() and toGroups().

Encoding & Character Limits

Encoding Single SMS Multipart (per part) Triggered By
GSM 7-bit 160 chars 153 chars Latin-only text
Unicode (UCS-2) 70 chars 67 chars Bengali, Arabic, emoji, etc.

Encoding is detected automatically by the API based on your message content. No configuration needed.

HTTP Status Codes & Exceptions

HTTP Code Exception Class Meaning
200 Success
202 Accepted — SMS queued for delivery
400 ValidationException Bad request — check your parameters
401 AuthenticationException Invalid or missing API token
402 InsufficientBalanceException Not enough balance
404 GioSMSException Resource not found (wrong message_id, batch_id, etc.)
422 ValidationException Validation error
429 RateLimitException Rate limit exceeded
500 GioSMSException Server error — try again later

License

MIT — see LICENSE for details.

Built with ❤️ by Riyad Munauwar