API v1.0 — Live

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/json

Auth Endpoints

POST/api/auth/login

Authenticate 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..."
  }
}
POST/api/auth/logout

Revoke the current token. Requires authentication.

GET/api/auth/me

Returns the authenticated user's profile including role and status.

Send SMS

POST/api/client/sms/send

Send a single SMS message to a recipient. Cost is deducted atomically from your wallet.

Request Body

ParameterTypeRequiredDescription
recipientstringRequiredRecipient phone number (e.g. +2348012345678, 2348012345678, or 08012345678)
sender_idstringRequiredApproved sender ID name (max 11 characters)
messagestringRequiredMessage 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
  }
}
GET/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

queuedMessage accepted and waiting to be dispatched to Jasmin
sentDispatched to Jasmin SMS Gateway and forwarded to carrier
deliveredDelivery receipt (DLR) confirmed by carrier
failedDelivery failed — check failure_reason
GET/api/client/sms/messages

List all messages sent from your account with pagination and filters.

Bulk SMS

POST/api/client/bulk-sms

Create a bulk SMS campaign. Messages are processed in chunks of 500 via the queue worker.

ParameterTypeRequiredDescription
namestringRequiredCampaign name for identification (max 255 characters)
sender_idinteger or stringRequiredYour approved sender: either its name (e.g. "CPLNG") or its numeric id (from /api/client/sender-id/approved)
message_textstringRequiredMessage content (max 1000 characters, billing per segment)
recipient_typestringRequiredOne of: all, contacts, groups, or manual
contact_idsarrayConditionalRequired when recipient_type is contacts. Array of contact IDs
group_idsarrayConditionalRequired when recipient_type is groups. Array of group IDs
phone_numbersarrayOptionalArray of phone numbers in E.164 format
manual_numbersstringOptionalComma-separated or newline-separated phone numbers
scheduled_atstringOptionalISO 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"
  }'
GET/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

draftqueuedprocessingcompletedcancelled
POST/api/client/bulk-sms/{id}/queue— Start dispatching a draft campaign
POST/api/client/bulk-sms/{id}/cancel— Cancel a queued or scheduled campaign
DELETE/api/client/bulk-sms/{id}— Delete a draft campaign

Wallet & Balance

GET/api/client/balance

Get 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"
}
GET/api/client/wallet/balance

Detailed wallet info including balance and currency.

GET/api/client/wallet/transactions

Paginated list of all credits, debits, and SMS charges.

POST/api/client/wallet/fund/initialize

Create a Paystack payment link to fund your wallet.

ParameterTypeDescription
amountnumberAmount 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"
  }
}
GET/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.

POST/api/client/sender-id/request

Submit 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"}'
GET/api/client/sender-id

List all your sender IDs and their approval status.

GET/api/client/sender-id/approved

List only approved sender IDs available for sending.

API Credentials

Manage HTTP API keys and SMPP credentials programmatically or from the dashboard.

GET/api/client/credentials/http

List 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"
    }
  ]
}
POST/api/client/credentials/http/create

Generate 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"
  }
}
POST/api/client/credentials/http/revoke/{id}

Permanently revoke an API key by its ID. This action cannot be undone.

GET/api/client/credentials/smpp

View your SMPP credentials and connection status.

POST/api/client/credentials/smpp/generate

Generate 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"
  }
}
POST/api/client/credentials/smpp/reset-password

Reset your SMPP password. New password shown once; all active sessions are terminated.

ParameterTypeDescription
credential_idintegerID 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.

Host
smpp.cpl.com.ng
Port
2775
Bind Type
transceiver
SMPP Version
3.4

Generate 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.

POST/api/webhooks/jasmin/dlr

Delivery 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"
}
POST/api/webhooks/paystack

Paystack 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 succeeded
201 CreatedResource created successfully (e.g. SMS queued, API key generated)
400 Bad RequestValidation failed — check the errors object for field-level details
401 UnauthorizedMissing or invalid API key
422 UnprocessableValidation errors, insufficient balance, or invalid sender ID
403 ForbiddenAccount suspended or SMPP access not approved
429 Too Many RequestsRate limit exceeded — back off and retry
500 Server ErrorInternal server error — contact support if it persists

Error 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.

100
Requests / minute
Standard limit for all accounts
Unlimited
Bulk campaign recipients
Processed asynchronously via queue

Rate Limit Headers

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1745145600

Best 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.