Skip to main content

HTTP Status Codes

Status CodeMeaningAction
200OKRequest succeeded
201CreatedResource created successfully
400Bad RequestFix request parameters or body
401UnauthorizedCheck API token or credentials
403ForbiddenAccount suspended or insufficient permissions
404Not FoundResource does not exist
429Rate LimitedSlow down, retry after X-RateLimit-Reset
500Internal ErrorServer error, retry with exponential backoff

Error Response Format

All errors return a JSON object with a human-readable message:
{
  "error": "to, from, and body are required"
}

Common Errors

Error MessageCauseSolution
to, from, and body are requiredMissing required fields in requestInclude all required parameters
invalid username or passwordAuthentication failedVerify credentials or API token
account is not activeAccount suspended or disabledContact support to reactivate account
pipeline processing failedRouting or billing configuration issueCheck gateway and billing settings
invalid phone number formatPhone number not in E.164 formatUse format: +[country_code][number]
insufficient balanceAccount balance too lowAdd credits to your account
rate limit exceededToo many requestsWait for reset or upgrade rate limit

Message-Level Errors

Some requests succeed with HTTP 200 but individual messages may fail. Check the error_code and error_message fields on each Message object. Example: Bulk send with partial failures
{
  "messages": [
    {
      "id": "msg_abc123",
      "to": "+8801712345678",
      "status": "delivered",
      "error_code": null,
      "error_message": null
    },
    {
      "id": "msg_def456",
      "to": "+1234567890",
      "status": "failed",
      "error_code": "INVALID_NUMBER",
      "error_message": "Phone number is invalid or unreachable"
    }
  ]
}

Error Code Categories

Search for specific error codes to understand failure reasons:
cURL
curl -X GET "https://api-message.nativehub.live/api/v1/error-codes/search?q=invalid" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
Node.js
const response = await fetch(
  'https://api-message.nativehub.live/api/v1/error-codes/search?q=invalid',
  {
    headers: {
      'Authorization': 'Bearer YOUR_API_TOKEN'
    }
  }
);

const errorCodes = await response.json();
console.log(errorCodes);
Python
response = requests.get(
    'https://api-message.nativehub.live/api/v1/error-codes/search',
    headers={'Authorization': 'Bearer YOUR_API_TOKEN'},
    params={'q': 'invalid'}
)

error_codes = response.json()
print(error_codes)
Common error code patterns:
Code PatternCategoryExamples
INVALID_*Validation failuresINVALID_NUMBER, INVALID_FORMAT
INSUFFICIENT_*Resource limitationsINSUFFICIENT_BALANCE, INSUFFICIENT_PERMISSIONS
CARRIER_*Carrier/network issuesCARRIER_REJECTED, CARRIER_TIMEOUT
BLOCKED_*Spam/compliance blocksBLOCKED_SPAM, BLOCKED_OPTED_OUT

Retry Strategies

Do NOT retry client errors (400, 401, 403, 404). These indicate problems with your request that will not resolve automatically.
Retry these status codes:
  • 429 Rate Limited: Wait until X-RateLimit-Reset timestamp, then retry
  • 500 Internal Error: Exponential backoff (1s, 2s, 4s, 8s…)
  • 503 Service Unavailable: Exponential backoff
Implementation example:
Node.js
async function sendWithRetry(message, maxRetries = 3) {
  let delay = 1000; // Start with 1 second

  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch('https://api-message.nativehub.live/api/v1/messages', {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer YOUR_API_TOKEN',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(message)
    });

    if (response.ok) {
      return await response.json();
    }

    // Don't retry client errors
    if (response.status >= 400 && response.status < 500 && response.status !== 429) {
      const error = await response.json();
      throw new Error(error.error);
    }

    // Retry with exponential backoff for 429 and 5xx
    if (response.status === 429 || response.status >= 500) {
      if (attempt < maxRetries - 1) {
        await new Promise(resolve => setTimeout(resolve, delay));
        delay *= 2; // Exponential backoff
        continue;
      }
    }

    throw new Error(`Request failed with status ${response.status}`);
  }
}
Python
import time
import requests

def send_with_retry(message, max_retries=3):
    delay = 1  # Start with 1 second

    for attempt in range(max_retries):
        response = requests.post(
            'https://api-message.nativehub.live/api/v1/messages',
            headers={
                'Authorization': 'Bearer YOUR_API_TOKEN',
                'Content-Type': 'application/json'
            },
            json=message
        )

        if response.ok:
            return response.json()

        # Don't retry client errors
        if 400 <= response.status_code < 500 and response.status_code != 429:
            raise Exception(response.json()['error'])

        # Retry with exponential backoff for 429 and 5xx
        if response.status_code == 429 or response.status_code >= 500:
            if attempt < max_retries - 1:
                time.sleep(delay)
                delay *= 2  # Exponential backoff
                continue

        raise Exception(f'Request failed with status {response.status_code}')

Idempotency

Prevent duplicate message sends by using the batch_id parameter for deduplication:
Node.js
const batchId = crypto.randomUUID();

const response = await fetch('https://api-message.nativehub.live/api/v1/messages', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    from: '+8801712345678',
    to: '+8801812345679',
    body: 'Your OTP is 123456',
    batch_id: batchId // Same batch_id will deduplicate
  })
});
Messages with identical batch_id values sent within 24 hours are treated as duplicates and only processed once.

Debugging Checklist

When troubleshooting API errors:
  1. Check HTTP status code category (4xx vs 5xx)
  2. Read the error field in the response body
  3. For message-level failures, check error_code and error_message
  4. Search error codes via /error-codes/search
  5. Verify phone numbers are in E.164 format
  6. Check account balance and active status
  7. Review rate limit headers
  8. Test with a known-good number (e.g., your own phone)