إرسال

Error Handling

HTTP status codes, error response format, and handling strategies

Error response format

All errors return a consistent JSON structure:

{
  "message": "Human-readable description",
  "code": "MACHINE_READABLE_CODE",
  "details": {}
}

HTTP status codes

StatusMeaning
200Success
400Bad request — invalid parameters
401Unauthorized — invalid or missing token
402Payment required — insufficient balance
403Forbidden — insufficient permissions
404Not found
429Rate limit exceeded
500Internal server error

Common error codes

CodeCause
UNAUTHORIZEDInvalid or expired API token
ACCESS_DENIEDToken lacks permission
INVALID_PHONEPhone number format is incorrect
MESSAGE_TOO_LONGMessage exceeds 1530 characters
INSUFFICIENT_BALANCEWallet balance too low
RATE_LIMIT_EXCEEDEDToo many requests

Handling errors in code

async function sendSms(payload) {
  const response = await fetch('https://sms.lamah.com/api/sms/messages', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.ERSAAL_API_TOKEN}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(payload),
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`${error.code}: ${error.message}`);
  }

  return response.json();
}
import requests

def send_sms(payload):
    response = requests.post(
        'https://sms.lamah.com/api/sms/messages',
        headers={'Authorization': f'Bearer {API_TOKEN}'},
        json=payload
    )

    if not response.ok:
        error = response.json()
        raise Exception(f"{error['code']}: {error['message']}")

    return response.json()

Retry with exponential backoff

For 429 and 500 errors, retry with increasing delays:

async function withRetry(fn, retries = 3, delay = 1000) {
  for (let i = 0; i < retries; i++) {
    try {
      return await fn();
    } catch (err) {
      if (i === retries - 1) throw err;
      await new Promise(r => setTimeout(r, delay * Math.pow(2, i)));
    }
  }
}

On this page