Documentation
SMS OTP API docs for Africa
One SMS API for Africa — send OTP and transactional SMS. There is no public email API.
Coverage we can defend
Published prepaid routes: Nigeria (1–3 credits / ₦6–₦18), Kenya (3 / ₦18), Ghana (3 / ₦18), South Africa (4 / ₦24), United Kingdom (8 / ₦48), Benin (25–56 / ₦150–₦336), Ivory Coast (56–79 / ₦336–₦474), United States (50 / ₦300). Source: GET /v1/pricing and the public pricing table. We do not publish a delivery-rate percentage. Signup trial is 10 free credits (₦60), not the US message price.
Pricing · Coverage · Security & SLA · Changelog · Status · API reference
Not a public product
Transactional email is not on this API. Resend/SMTP are used only for account mail (verification, receipts, invites). There is no Python SDK on PyPI. PHP is shipped as robase/sdk — it is not “coming Q3”.
Official SDKs
First-party clients for Node.js, Go, and PHP. All three wrap the same REST API — send OTP, verify OTP, send transactional SMS — with Bearer token auth, automatic retries, and idempotency keys. Any other language can call the REST API directly.
Zero dependencies. ESM + CommonJS with full types. Node 20+, Deno, Bun, and edge runtimes.
npm install @robasedev/sdk import { Robase } from "@robasedev/sdk";
const robase = new Robase({ apiKey: process.env.ROBASE_API_KEY });
const sent = await robase.otp.send({ phone_number: "+2348012345678" });
const result = await robase.otp.verify({ otp_id: sent.id, code: "123456" });
await robase.sms.send({
phone_number: "+2348012345678",
message: "Your order #12345 has shipped."
});Go
Standard library only — no third-party dependencies. The client is safe for concurrent use.
go get github.com/mantissatech/robase-sdk-go import robase "github.com/mantissatech/robase-sdk-go"
client, err := robase.New(os.Getenv("ROBASE_API_KEY"))
sent, err := client.OTP.Send(ctx, robase.SendOTPParams{
PhoneNumber: "+2348012345678",
})
result, err := client.OTP.Verify(ctx, robase.VerifyOTPParams{
OTPID: sent.ID,
Code: "123456",
})
msg, err := client.SMS.Send(ctx, robase.SendSMSParams{
PhoneNumber: "+2348012345678",
Message: "Your order #12345 has shipped.",
})PHP 8.1+. No framework dependencies — just ext-curl and ext-json.
composer require robase/sdk $robase = new Robase\Client(getenv('ROBASE_API_KEY'));
$sent = $robase->otp->send('+2348012345678');
$result = $robase->otp->verify($sent->id, '123456');
$msg = $robase->sms->send(
phoneNumber: '+2348012345678',
message: 'Your order #12345 has shipped.',
);REST API
The SDKs are thin wrappers over these endpoints. Base URL: https://api.robase.dev.
Authentication
All API requests require a Bearer token. Live keys start with robe_ (robe_ plus 64 hex characters). There is no rb_test_ or sk_live_ prefix.
curl -X POST https://api.robase.dev/v1/otp/send \ -H "Authorization: Bearer robe_xxx" \ -H "Content-Type: application/json" \ -d {"phone_number":"+2348012345678"}
Send OTP
Send a one-time password to a phone number.
POST /v1/otp/send { "phone_number": "+2348012345678", "code_length": 6, "ttl_seconds": 600, "language": "fr" }
language is optional — omit it and the message uses your workspace’s default language. Accept-Language changes error prose only, never the SMS itself.
Verify OTP
Verify a one-time password using the OTP ID and code.
POST /v1/otp/verify { "otp_id": "...", "code": "123456" }
Send Transactional SMS
Send an arbitrary SMS message to a phone number. Uses the same routing and credit billing as OTPs.
POST /v1/sms/send { "phone_number": "+2348012345678", "message": "Your order #12345 has shipped.", "metadata": { "order_id": "12345" } }
The response returns a message ID you can use to check delivery status.
GET /v1/sms/{id} # → 200 { "id": "550e8400-...", "phone_number": "+2348012345678", "country_code": "NG", "message": "Your order #12345 has shipped.", "status": "delivered", "credit_cost": 1 }
Status transitions: pending → sent → delivered (or failed). Webhook events: sms.sent, sms.delivered, sms.failed.