Key Takeaways
- CodeIgniter SMS gateway with Android device OTP: server-side HTTPS to POST /messages; the SIM sends the code.
- /codebase-php owns REST samples. This is not a Complete PHP SDK or composer package.
- Accept is not delivered. Webhooks or GET /messages/{id} for DLR.
- Priced by devices and SMS send volume. You use your own phone and operator SMS credit. Paid from $19/month on the hosted path.
- Free 300 SMS lifetime is for canaries.
- Keep OTP templates boring and off the promo radio.
CodeIgniter OTP on an android sms gateway api is a getenv key and a queue, not a helper in the view. Samples: PHP HTTPS. Use case: OTP verification. Templates: OTP copy.
Priced by devices and SMS send volume. You use your own phone and operator SMS credit.
If the CodeIgniter controller prints the OTP into the HTML “for debugging,” you do not have 2FA. You have a screenshot waiting to happen. Persist the hash, SMS the code, log the message id.
curl/PHP, not a composer SDK
No “Download PHP SDK.” Env file, not committed config. Developer Center owns fields.
OTP path in CodeIgniter
| Step | CI / your app | Gateway / phone |
|---|---|---|
| Issue | Generate code, store hash, TTL | — |
| Send | Worker POST /messages | Queue to Android |
| Radio | — | SIM + operator airtime |
| Verify | Compare hash, expire | DLR webhook optional |
POST JSON from the server
<?php
// SMS Gateway — POST /api/v1/messages (Bearer JSON). Docs: https://docs.sms-gateway.app/
$url = 'https://app.sms-gateway.app/api/v1/messages';
$key = getenv('SMS_GATEWAY_API_KEY'); // never commit real keys
$payload = json_encode([
'to' => ['+14155552671'], // E.164 with +
'text' => 'Hello from SMS Gateway!',
'type' => 'sms',
]);
$ctx = stream_context_create([
'http' => [
'method' => 'POST',
'header' => implode("\r\n", [
'Authorization: Bearer ' . $key,
'Content-Type: application/json',
'Idempotency-Key: ' . bin2hex(random_bytes(16)),
]),
'content' => $payload,
'timeout' => 30,
'ignore_errors' => true,
],
]);
$response = file_get_contents($url, false, $ctx);
$result = json_decode($response, true);
if (!empty($result['messages'][0]['id'])) {
$id = $result['messages'][0]['id'];
echo 'Queued. Message ID: ' . $id;
} else {
$err = $result['error']['code'] ?? 'unknown';
echo 'Error: ' . $err . ' — ' . ($result['error']['message'] ?? $response);
}
E.164 in to[]. Number formats.
TTL lives in your app
If the phone was offline, drop stale codes. Offline queues.
Dedicated OTP device
Priority queues cannot split one SIM. Setup.
Laravel is a sibling, not this page
Laravel architecture lives on its own guides. Do not turn this CodeIgniter spoke into a second Laravel cornerstone.
Checklist
- Key in env; CI 4/3 getenv in workers only.
- Hash stored; body not logged.
- Idempotency-Key per attempt.
- OTP device isolated and funded.
- Webhook HMAC if you trust DLR.
- Staff canary passed.
Next steps
Copy from PHP samples, then pair. Devices + volume; operator airtime is yours.
Related product pages
Jump to the live product docs for this topic—not another long-form article.
- OTP and 2FA SMS on AndroidAuthentication flows
- SMS API documentationLive endpoint reference
- device and SMS volume pricingPlans and allowances
- Android SMS gateway product guideDefinition, product, and how to buy




