API Documentation
Complete reference for integrating CPLSMS into your applications. Base URL: https://api.cpl.com.ng/api
Quick Start
1. Get Your API Key
Log in to your CPLSMS dashboard and generate an HTTP API key from API Credentials → HTTP API Keys → Generate New Key. Keys are prefixed with cpl_.
2. Make Your First Request
curl -X POST https://api.cpl.com.ng/api/client/sms/send \
-H "Authorization: Bearer cpl_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"recipient": "+2348012345678",
"sender_id": "MyBrand",
"message": "Hello from CPLSMS API!"
}'3. Handle the Response
{
"message": "SMS queued for sending",
"data": {
"message_id": 12345,
"segments": 1,
"cost": 2.50,
"status": "queued",
"new_balance": 14997.50
}
}Authentication
CPLSMS supports two authentication methods:
HTTP API Key
For server-to-server integrations. Pass via Authorization: Bearer header.
Session (Dashboard)
Cookie-based session auth for the web dashboard, powered by Laravel Sanctum.
Keep your API key secure! Keys are prefixed with cpl_ and are only shown once. Store them in environment variables — never in client-side code or public repositories.
Always include the Accept: application/json header in all API requests. This ensures the server returns JSON error responses instead of HTML redirects when validation fails.
Required Headers
Authorization: Bearer cpl_your_api_key_here
Accept: application/json
Content-Type: application/jsonAuth Endpoints
/api/auth/loginAuthenticate with email and password. Returns a Sanctum token.
curl -X POST https://api.cpl.com.ng/api/auth/login \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"email": "you@example.com", "password": "secret"}'{
"success": true,
"data": {
"user": { "id": 1, "name": "John Doe", "role": "client" },
"token": "1|abc123xyz..."
}
}/api/auth/logoutRevoke the current token. Requires authentication.
/api/auth/meReturns the authenticated user's profile including role and status.
Send SMS
/api/client/sms/sendSend a single SMS message to a recipient. Cost is deducted atomically from your wallet.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
recipient | string | Required | Recipient phone number (e.g. +2348012345678, 2348012345678, or 08012345678) |
sender_id | string | Required | Approved sender ID name (max 11 characters) |
message | string | Required | Message content. ≤160 chars = 1 segment; longer messages billed per 153-char segment |
Example
curl -X POST https://api.cpl.com.ng/api/client/sms/send \
-H "Authorization: Bearer cpl_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"recipient": "+2348012345678",
"sender_id": "MyBrand",
"message": "Your OTP is 123456. Valid for 10 minutes."
}'Response (201 Created)
{
"message": "SMS queued for sending",
"data": {
"message_id": 12345,
"segments": 1,
"cost": 2.50,
"status": "queued",
"new_balance": 14997.50
}
}/api/client/sms/status/{id}Get delivery status of a specific message.
curl https://api.cpl.com.ng/api/client/sms/status/12345 \
-H "Authorization: Bearer cpl_YOUR_API_KEY" \
-H "Accept: application/json"{
"data": {
"id": 12345,
"user_id": 1,
"recipient_phone": "+2348012345678",
"sender_id_value": "MyBrand",
"message_text": "Your OTP is 123456.",
"segments_count": 1,
"cost": "2.50",
"status": "delivered",
"created_at": "2025-04-20T10:30:00.000000Z",
"updated_at": "2025-04-20T10:30:08.000000Z"
}
}Status Values
failure_reason/api/client/sms/messagesList all messages sent from your account with pagination and filters.
Bulk SMS
/api/client/bulk-smsCreate a bulk SMS campaign. Messages are processed in chunks of 500 via the queue worker.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Required | Campaign name for identification (max 255 characters) |
sender_id | integer or string | Required | Your approved sender: either its name (e.g. "CPLNG") or its numeric id (from /api/client/sender-id/approved) |
message_text | string | Required | Message content (max 1000 characters, billing per segment) |
recipient_type | string | Required | One of: all, contacts, groups, or manual |
contact_ids | array | Conditional | Required when recipient_type is contacts. Array of contact IDs |
group_ids | array | Conditional | Required when recipient_type is groups. Array of group IDs |
phone_numbers | array | Optional | Array of phone numbers in E.164 format |
manual_numbers | string | Optional | Comma-separated or newline-separated phone numbers |
scheduled_at | string | Optional | ISO 8601 datetime to schedule dispatch (must be in the future) |
curl -X POST https://api.cpl.com.ng/api/client/bulk-sms \
-H "Authorization: Bearer cpl_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"name": "April Promo",
"sender_id": "CPLNG",
"message_text": "50% off all items this weekend. Visit our store!",
"recipient_type": "manual",
"phone_numbers": ["+2348012345678", "+2348087654321"],
"scheduled_at": "2025-04-25T09:00:00Z"
}'/api/client/bulk-sms/{id}Get the status and progress of a bulk SMS campaign.
{
"success": true,
"data": {
"id": 42,
"name": "April Promo",
"status": "processing",
"total_recipients": 1500,
"sent": 900,
"delivered": 850,
"failed": 12,
"total_cost": 3750.00,
"scheduled_at": null,
"created_at": "2025-04-20T08:00:00Z"
}
}Campaign Status Values
/api/client/bulk-sms/{id}/queue— Start dispatching a draft campaign/api/client/bulk-sms/{id}/cancel— Cancel a queued or scheduled campaign/api/client/bulk-sms/{id}— Delete a draft campaignWallet & Balance
/api/client/balanceGet your current wallet balance.
curl https://api.cpl.com.ng/api/client/balance \
-H "Authorization: Bearer cpl_YOUR_API_KEY" \
-H "Accept: application/json"{
"balance": 15000.00,
"currency": "NGN"
}/api/client/wallet/balanceDetailed wallet info including balance and currency.
/api/client/wallet/transactionsPaginated list of all credits, debits, and SMS charges.
/api/client/wallet/fund/initializeCreate a Paystack payment link to fund your wallet.
| Parameter | Type | Description |
|---|---|---|
amount | number | Amount to fund in your wallet currency (minimum 100 NGN or 1 USD) |
curl -X POST https://api.cpl.com.ng/api/client/wallet/fund/initialize \
-H "Authorization: Bearer cpl_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"amount": 5000}'{
"data": {
"reference": "CPL-20250420-XYZ",
"authorization_url": "https://checkout.paystack.com/abc123",
"amount": 5000,
"currency": "NGN"
}
}/api/client/wallet/fund/verify/{reference}Verify a Paystack payment and credit the wallet if successful. Call this after the user returns from Paystack checkout.
curl https://api.cpl.com.ng/api/client/wallet/fund/verify/CPL-20250420-XYZ \
-H "Authorization: Bearer cpl_YOUR_API_KEY" \
-H "Accept: application/json"Sender IDs
Sender IDs must be approved before use. Approval typically takes 1–2 business days. Sending with an unapproved sender ID will return a 422 error.
/api/client/sender-id/requestSubmit a sender ID for approval. Max 11 characters, alphanumeric.
curl -X POST https://api.cpl.com.ng/api/client/sender-id/request \
-H "Authorization: Bearer cpl_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"sender_name": "MyBrand"}'/api/client/sender-idList all your sender IDs and their approval status.
/api/client/sender-id/approvedList only approved sender IDs available for sending.
API Credentials
Manage HTTP API keys and SMPP credentials programmatically or from the dashboard.
/api/client/credentials/httpList all your HTTP API keys (keys are masked — full value shown only on creation).
{
"success": true,
"data": [
{
"id": 3,
"name": "Production Key",
"key_preview": "cpl_a1b2c3d4...",
"last_used_at": "2025-04-19T14:22:00Z",
"created_at": "2025-01-10T09:00:00Z"
}
]
}/api/client/credentials/http/createGenerate a new HTTP API key. The full key is only shown once — store it securely.
curl -X POST https://api.cpl.com.ng/api/client/credentials/http/create \
-H "Authorization: Bearer cpl_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"name": "My Server Key"}'// 201 Created
{
"success": true,
"message": "API key created successfully. Please copy it now as it will not be shown again.",
"data": {
"id": 4,
"name": "My Server Key",
"api_key": "cpl_AbCdEfGhIjKlMnOpQrStUvWxYz...",
"created_at": "2025-04-20T10:30:00.000000Z"
}
}/api/client/credentials/http/revoke/{id}Permanently revoke an API key by its ID. This action cannot be undone.
/api/client/credentials/smppView your SMPP credentials and connection status.
/api/client/credentials/smpp/generateGenerate SMPP credentials. Username is auto-assigned. Password shown once.
// 201 Created
{
"success": true,
"message": "SMPP credentials generated successfully. Please copy them now as the password will not be shown again.",
"data": {
"id": 1,
"smpp_username": "smpp_AbCdEfGhIj",
"smpp_password": "xK9mP2qR",
"status": "active",
"connection_info": {
"host": "smpp.cpl.com.ng",
"port": 2775,
"bind_type": "transceiver"
},
"created_at": "2025-04-20T10:30:00.000000Z"
}
}/api/client/credentials/smpp/reset-passwordReset your SMPP password. New password shown once; all active sessions are terminated.
| Parameter | Type | Description |
|---|---|---|
credential_id | integer | ID of the SMPP credential to reset (required) |
SMPP Integration
Connect directly to CPLSMS via the SMPP protocol for high-throughput messaging. Ideal for telcos, aggregators, and applications requiring persistent connections.
smpp.cpl.com.ng2775transceiver3.4Generate your SMPP username and password from the client dashboard under API Credentials → SMPP, or via the /api/client/credentials/smpp/generate endpoint above.
Webhooks
CPLSMS exposes webhook endpoints for real-time delivery reports and Paystack payment notifications.
/api/webhooks/jasmin/dlrDelivery Report (DLR) callback from Jasmin SMS Gateway. Automatically updates message status to delivered or failed. No client action required.
{
"msgid": "jasmin-abc123",
"to": "+2348012345678",
"status": "DELIVRD",
"err": "000"
}/api/webhooks/paystackPaystack payment webhook. Verifies the HMAC-SHA512 x-paystack-signature header and credits the user's wallet on successful charge.success events. Configure this URL in your Paystack dashboard settings.
Error Codes
CPLSMS uses standard HTTP status codes. All error responses share a consistent JSON envelope.
200 OKRequest succeeded201 CreatedResource created successfully (e.g. SMS queued, API key generated)400 Bad RequestValidation failed — check the errors object for field-level details401 UnauthorizedMissing or invalid API key422 UnprocessableValidation errors, insufficient balance, or invalid sender ID403 ForbiddenAccount suspended or SMPP access not approved429 Too Many RequestsRate limit exceeded — back off and retry500 Server ErrorInternal server error — contact support if it persistsError Response Format
{
"success": false,
"message": "Insufficient wallet balance",
"errors": {
"balance": "You need ₦50.00 but only have ₦25.00"
}
}Rate Limiting
API requests are rate-limited to ensure fair usage and system stability.
Rate Limit Headers
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1745145600Best Practices
Always include the Accept: application/json header
This ensures the API returns JSON error responses instead of HTML redirects. Include it in every request alongside Content-Type and Authorization headers.
Always use E.164 format for phone numbers
Format: +[country code][number]. Example: +2348012345678. Nigerian local formats (e.g. 08012345678) are also accepted and auto-converted.
Check balance before large bulk sends
Use GET /api/client/balance to verify sufficient funds. The API will reject sends with 422 if balance is insufficient.
Implement exponential backoff on 429 errors
Wait progressively longer between retries — start at 1s, double each attempt, cap at 60s.
Use the bulk-sms endpoint for mass messaging
For more than 10 recipients, always use POST /api/client/bulk-sms — optimised for high volumes with async queue processing.
Keep API keys in environment variables
Never hard-code keys in source code. Rotate compromised keys immediately via the dashboard.
Pre-register sender IDs before campaigns
Submit and get sender IDs approved at least 2 business days before your campaign launch.
Verify Paystack webhook signatures
CPLSMS verifies the x-paystack-signature header on every webhook call. Do not rely on IP filtering alone.
Need Help?
Our support team is here to help you integrate and succeed with CPLSMS.