devriyad / giosms
Official PHP SDK for GioSMS — Send SMS easily from any PHP or Laravel application.
Requires
- php: ^8.1
- guzzlehttp/guzzle: ^7.0
This package is auto-updated.
Last update: 2026-03-14 14:51:27 UTC
README
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
- Installation
- Setup — Laravel
- Setup — Standalone PHP (Without Laravel)
- Usage
- Error Handling
- Laravel Dependency Injection
- Reference
- License
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
.envto your.gitignoreso 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
typeis automatically set tootp— 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
messageortemplate_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: queued → submitted → delivered 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