API Usage v1 (archive)
Old APIs only. Send SMS messages and OTP codes using the ChinqIT Verify REST API (v1 endpoints).
:::info Deprecated guide This guide documents the deprecated v1 endpoints. For the current API, see API Reference. :::
Quick Start (deprecated)
The endpoints below are deprecated. v1 responses include a deprecation object and Deprecation: true header. Use API Reference for current endpoints.
Step 1: Send a message
curl -X POST https://sms.chinqit.com/messages/send \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+22238089336",
"message": "Hello from ChinqIT Verify!"
}'Step 2: Send and verify an OTP
# Send OTP
curl -X POST https://sms.chinqit.com/otp/send \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+22238089336",
"language": "en"
}'
# Verify OTP
curl -X POST https://sms.chinqit.com/otp/verify \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+22238089336",
"otp": "123456"
}'See API v1 Endpoints for authentication, base URL, and phone number format.
Endpoints
Send SMS — POST /messages/send
Send an SMS message to a phone number (deprecated v1 endpoint).
Endpoint: POST /messages/send
Request:
{
"phoneNumber": "+1234567890",
"message": "Your message text here"
}Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
phoneNumber | string | Yes | Recipient phone number (Mauritania format). Accepted formats: +222XXXXXXXX, 222XXXXXXXX, or XXXXXXXX. API normalizes and stores as +222XXXXXXXX. See API v1 Endpoints for details. |
message | string | Yes | SMS message content (min 1 character) |
Response:
{
"success": true,
"messageId": "550e8400-e29b-41d4-a716-446655440000",
"queued": true
}Example:
curl -X POST https://sms.chinqit.com/messages/send \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+22238089336",
"message": "Hello from ChinqIT Verify!"
}'JavaScript:
const response = await fetch("https://sms.chinqit.com/messages/send", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": "YOUR_API_KEY",
},
body: JSON.stringify({
phoneNumber: "+22238089336",
message: "Hello from ChinqIT Verify!",
}),
});
const data = await response.json();
console.log("Message ID:", data.messageId);Python:
import requests
response = requests.post(
'https://sms.chinqit.com/messages/send',
headers={
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={
'phoneNumber': '+22238089336',
'message': 'Hello from ChinqIT Verify!'
}
)
data = response.json()
print(f"Message ID: {data['messageId']}")PHP:
<?php
$ch = curl_init('https://sms.chinqit.com/messages/send');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-API-Key: YOUR_API_KEY',
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'phoneNumber' => '+22238089336',
'message' => 'Hello from ChinqIT Verify!'
]));
$response = curl_exec($ch);
$data = json_decode($response, true);
echo "Message ID: " . $data['messageId'];
curl_close($ch);
?>Note: Messages are queued and processed asynchronously. The API returns immediately with a
messageIdthat you can use to track your message.
Send OTP — POST /otp/send
Note: The v1 OTP route is frozen. It does not support email OTP. Use
POST /api/v2/codewithchannel: "email"and
Send a one-time password (OTP) code via SMS or WhatsApp (deprecated v1 endpoint).
Endpoint: POST /otp/send
Request:
{
"phoneNumber": "+22238089336",
"hash": "ABC123XYZ45",
"language": "en",
"channel": "sms"
}Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
phoneNumber | string | Yes | Phone number to send OTP to (Mauritania format). Accepted formats: +222XXXXXXXX, 222XXXXXXXX, or XXXXXXXX. API normalizes and stores as +222XXXXXXXX. See API v1 Endpoints for details. |
hash | string | No | 11-character SMS Retriever hash (SMS channel only). When provided, the hash will be appended to the OTP message on a new line. See SMS Retriever Guide for implementation details. |
language | string | No | Language code: fr (default), en, or ar |
channel | string | No | Communication channel: sms (default) or whatsapp |
Response:
{
"success": true,
"messageId": "550e8400-e29b-41d4-a716-446655440000",
"expiresIn": 600
}SMS Channel Example:
curl -X POST https://sms.chinqit.com/otp/send \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+22238089336",
"language": "en",
"channel": "sms"
}'WhatsApp Channel Example:
curl -X POST https://sms.chinqit.com/otp/send \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+22238089336",
"language": "en",
"channel": "whatsapp"
}'JavaScript:
// Send OTP via SMS
const smsResponse = await fetch("https://sms.chinqit.com/otp/send", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": "YOUR_API_KEY",
},
body: JSON.stringify({
phoneNumber: "+22238089336",
language: "en",
channel: "sms",
}),
});
// Send OTP via WhatsApp
const whatsappResponse = await fetch("https://sms.chinqit.com/otp/send", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": "YOUR_API_KEY",
},
body: JSON.stringify({
phoneNumber: "+22238089336",
language: "en",
channel: "whatsapp",
}),
});
const data = await whatsappResponse.json();
console.log("OTP expires in:", data.expiresIn, "seconds");Python:
import requests
# Send OTP via SMS
sms_response = requests.post(
'https://sms.chinqit.com/otp/send',
headers={
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={
'phoneNumber': '+22238089336',
'language': 'en',
'channel': 'sms'
}
)
# Send OTP via WhatsApp
whatsapp_response = requests.post(
'https://sms.chinqit.com/otp/send',
headers={
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={
'phoneNumber': '+22238089336',
'language': 'en',
'channel': 'whatsapp'
}
)
data = whatsapp_response.json()
print(f"OTP expires in: {data['expiresIn']} seconds")OTP Details:
- 6-digit numeric code
- Valid for 10 minutes
- Maximum 3 verification attempts
- Available via SMS or WhatsApp
SMS Retriever Hash Example (SMS OTP):
To enable automatic SMS consumption using Android's SMS Retriever API, include an 11-character hash in your /otp/send request. The hash will be appended to your OTP message:
const response = await fetch("https://sms.chinqit.com/otp/send", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": "YOUR_API_KEY",
},
body: JSON.stringify({
phoneNumber: "+22238089336",
channel: "sms",
language: "en",
hash: "ABC123XYZ45", // 11-character hash
}),
});The resulting SMS will be:
Your verification code is: 123456
ABC123XYZ45Verify OTP
Note: The v1 OTP route is frozen. It does not support email OTP. Use
POST /api/v2/checkwithchannel: "email"and
Verify an OTP code that was sent to a phone number (deprecated v1 endpoint).
Endpoint: POST /otp/verify
Request:
{
"phoneNumber": "+22238089336",
"otp": "123456",
"channel": "sms"
}Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
phoneNumber | string | Yes | Phone number the OTP was sent to (Mauritania format). Accepted formats: +222XXXXXXXX, 222XXXXXXXX, or XXXXXXXX. API normalizes and stores as +222XXXXXXXX. See API v1 Endpoints for details. |
otp | string | Yes | 6-digit OTP code to verify |
channel | string | No | Communication channel used: sms (default) or whatsapp |
Response (Success):
{
"success": true,
"message": "OTP verified successfully",
"verified": true
}Response (Invalid):
{
"success": false,
"message": "Invalid OTP",
"retriesLeft": 2
}Example:
curl -X POST https://sms.chinqit.com/otp/verify \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+22238089336",
"otp": "123456",
"channel": "sms"
}'JavaScript:
const response = await fetch("https://sms.chinqit.com/otp/verify", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": "YOUR_API_KEY",
},
body: JSON.stringify({
phoneNumber: "+22238089336",
otp: "123456",
channel: "sms",
}),
});
const data = await response.json();
if (data.verified) {
console.log("OTP verified successfully");
} else {
console.log("Invalid OTP. Retries left:", data.retriesLeft);
}Error Handling
Error Response Format
All errors follow this format:
{
"success": false,
"message": "Error description",
"errors": [] // Optional: Validation errors
}HTTP Status Codes
| Code | Description |
|---|---|
| 200 | Success |
| 400 | Bad Request - Validation error |
| 401 | Unauthorized - Missing API key |
| 403 | Forbidden - Invalid API key |
| 404 | Not Found |
| 429 | Too Many Requests - Rate limit exceeded |
| 500 | Internal Server Error |
| 502 | Bad Gateway - Provider error (WhatsApp channel) |
Common Errors
Validation Error (400):
{
"success": false,
"message": "Validation failed",
"errors": [
{
"path": ["message"],
"message": "String must contain at least 1 character(s)"
}
]
}Invalid Phone Number (400):
{
"success": false,
"message": "Validation failed",
"errors": [
{
"path": ["phoneNumber"],
"message": "Phone number must be a valid Mauritania number. Accepted formats: +222XXXXXXXX, 222XXXXXXXX, or XXXXXXXX (where XXXXXXXX starts with 2, 3, or 4)."
}
]
}Rate Limit Exceeded (429):
{
"success": false,
"message": "Rate limit exceeded. Please try again later."
}WhatsApp Provider Error (502):
{
"success": false,
"message": "WhatsApp OTP send failed",
"error": "Error details from WhatsApp API"
}Rate Limits
OTP Sending
Per phone number per API key.
You set these limits on each API key in the dashboard: per minute, per hour and per day. If you leave them empty, the maximum applies:
- 60 requests per minute
- 1,000 requests per hour
- 5,000 requests per day
Code Examples
Complete JavaScript Example
class ChinqitVerifyClient {
constructor(apiKey, baseUrl = "https://sms.chinqit.com") {
this.apiKey = apiKey;
this.baseUrl = baseUrl;
}
async request(endpoint, options = {}) {
const url = `${this.baseUrl}${endpoint}`;
const response = await fetch(url, {
...options,
headers: {
"Content-Type": "application/json",
"X-API-Key": this.apiKey,
...options.headers,
},
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || "API request failed");
}
return response.json();
}
async sendMessage(phoneNumber, message) {
return this.request("/messages/send", {
method: "POST",
body: JSON.stringify({
phoneNumber,
message,
}),
});
}
async sendOTP(phoneNumber, language = "fr", channel = "sms") {
return this.request("/otp/send", {
method: "POST",
body: JSON.stringify({
phoneNumber,
language,
channel,
}),
});
}
async verifyOTP(phoneNumber, otp, channel = "sms") {
const response = await this.request("/otp/verify", {
method: "POST",
body: JSON.stringify({ phoneNumber, otp, channel }),
});
return response.verified === true;
}
}
// Usage
const client = new ChinqitVerifyClient("YOUR_API_KEY");
// Send a message
const result = await client.sendMessage("+22238089336", "Hello!");
console.log("Message ID:", result.messageId);
// Send and verify OTP via SMS
const smsOtpResult = await client.sendOTP("+22238089336", "en", "sms");
const smsVerified = await client.verifyOTP("+22238089336", "123456", "sms");
console.log("SMS OTP verified:", smsVerified);
// Send and verify OTP via WhatsApp
const whatsappOtpResult = await client.sendOTP(
"+22238089336",
"en",
"whatsapp",
);
const whatsappVerified = await client.verifyOTP(
"+22238089336",
"123456",
"whatsapp",
);
console.log("WhatsApp OTP verified:", whatsappVerified);Complete Python Example
import requests
from typing import Optional, Dict
class ChinqitVerifyClient:
def __init__(self, api_key: str, base_url: str = 'https://sms.chinqit.com'):
self.api_key = api_key
self.base_url = base_url
self.headers = {
'Content-Type': 'application/json',
'X-API-Key': api_key
}
def _request(self, method: str, endpoint: str, data: Optional[Dict] = None):
url = f'{self.base_url}{endpoint}'
response = requests.request(method, url, json=data, headers=self.headers)
response.raise_for_status()
return response.json()
def send_message(self, phone_number: str, message: str):
return self._request('POST', '/messages/send', {
'phoneNumber': phone_number,
'message': message
})
def send_otp(self, phone_number: str, language: str = 'fr', channel: str = 'sms'):
return self._request('POST', '/otp/send', {
'phoneNumber': phone_number,
'language': language,
'channel': channel
})
def verify_otp(self, phone_number: str, otp: str, channel: str = 'sms'):
response = self._request('POST', '/otp/verify', {
'phoneNumber': phone_number,
'otp': otp,
'channel': channel
})
return response.get('verified', False)
# Usage
client = ChinqitVerifyClient('YOUR_API_KEY')
# Send a message
result = client.send_message('+22238089336', 'Hello!')
print(f"Message ID: {result['messageId']}")
# Send and verify OTP via SMS
sms_otp_result = client.send_otp('+22238089336', 'en', 'sms')
sms_verified = client.verify_otp('+22238089336', '123456', 'sms')
print(f"SMS OTP verified: {sms_verified}")
# Send and verify OTP via WhatsApp
whatsapp_otp_result = client.send_otp('+22238089336', 'en', 'whatsapp')
whatsapp_verified = client.verify_otp('+22238089336', '123456', 'whatsapp')
print(f"WhatsApp OTP verified: {whatsapp_verified}")Common Use Cases
User Registration with OTP
// Step 1: Send OTP via SMS
const smsOtpResult = await client.sendOTP("+22238089336", "en", "sms");
// Step 2: User enters OTP (from your UI)
const userOTP = "123456"; // Get from user input
// Step 3: Verify OTP
try {
const verified = await client.verifyOTP("+22238089336", userOTP, "sms");
if (verified) {
// Proceed with registration
console.log("OTP verified, user can register");
}
} catch (error) {
// Handle invalid/expired OTP
console.error("OTP verification failed:", error.message);
}User Registration with WhatsApp OTP
// Step 1: Send OTP via WhatsApp
const whatsappOtpResult = await client.sendOTP("+1234567890", "en", "whatsapp");
// Step 2: User enters OTP (from your UI)
const userOTP = "123456"; // Get from user input
// Step 3: Verify OTP
try {
const verified = await client.verifyOTP("+22238089336", userOTP, "whatsapp");
if (verified) {
// Proceed with registration
console.log("WhatsApp OTP verified, user can register");
}
} catch (error) {
// Handle invalid/expired OTP or provider errors
console.error("WhatsApp OTP verification failed:", error.message);
}Bulk Messaging
async function sendBulkMessages(recipients, message) {
const results = [];
for (const phoneNumber of recipients) {
try {
// Add delay to respect rate limits
if (results.length > 0) {
await new Promise((resolve) => setTimeout(resolve, 5000));
}
const result = await client.sendMessage(phoneNumber, message);
results.push({
phoneNumber,
messageId: result.messageId,
status: "queued",
});
} catch (error) {
results.push({ phoneNumber, error: error.message, status: "failed" });
}
}
return results;
}
// Usage
const recipients = ["+22238089336", "+22234567890", "+22241234567"];
const results = await sendBulkMessages(recipients, "Bulk message");
console.log(results);Best Practices
Security
- ✅ Never commit API keys to version control
- ✅ Use environment variables or secure secret management
- ✅ Rotate API keys periodically
- ✅ Use HTTPS for all API requests
Error Handling
- ✅ Always check the
successfield in responses - ✅ Implement retry logic with exponential backoff for transient errors (429, 500, 502)
- ✅ Handle rate limits gracefully
- ✅ Log errors for debugging and monitoring
Performance
- ✅ Store
messageIdfor tracking purposes - ✅ Use async/await or promises for non-blocking calls
- ✅ Implement proper timeout handling
- ✅ Don't send duplicate messages
OTP Best Practices
- ✅ Always verify OTPs server-side
- ✅ Don't expose OTP codes in logs
- ✅ Handle rate limits gracefully
- ✅ Choose appropriate channel (SMS or WhatsApp) based on user preference
- ✅ Handle WhatsApp provider errors (502) with fallback to SMS if needed
Support
- API v1 Reference (Deprecated): See API v1 Reference (Deprecated) for legacy endpoint details
- Troubleshooting: Check Troubleshooting Guide for common issues
Need help? Contact ChinqIT Verify support or refer to the troubleshooting guide.