Skip to main content
Hany uses standard HTTP status codes to indicate whether a request succeeded or failed. Any response with a 4xx or 5xx status code includes a JSON body that gives you a machine-readable error code and a human-readable message — so your integration can respond intelligently without parsing free-form text.

Error Response Format

Every error response follows this consistent shape:
{
  "status": "error",
  "code": "invalid_recipient",
  "message": "The recipient phone number is not in a valid E.164 format."
}
status
string
Always "error" for failed requests.
code
string
A stable, snake_case identifier for the error type. Use this field in your application logic — the message field is for humans and may change.
message
string
A plain-English description of what went wrong, suitable for logging or displaying to internal users.

HTTP Status Codes

StatusMeaning
200 OKThe request succeeded.
201 CreatedA resource was successfully created (e.g., a new Sender ID was registered).
400 Bad RequestThe request is malformed or contains invalid parameters.
401 UnauthorizedThe Authorization header is missing or contains an invalid API key.
403 ForbiddenThe API key is valid but does not have permission to perform this action.
404 Not FoundThe requested resource does not exist.
422 Unprocessable EntityThe request is well-formed but failed validation (e.g., insufficient credits).
429 Too Many RequestsYou have exceeded the rate limit. Slow down and retry.
500 Internal Server ErrorAn unexpected error occurred on Hany’s servers. Contact support if it persists.

Common Error Codes

Error CodeHTTP StatusDescription
unauthorized401API key is missing or invalid. Check your Authorization header.
forbidden403Your API key does not have permission to perform this action.
invalid_recipient400The recipient phone number is not in valid E.164 format (e.g., +233XXXXXXXXX).
invalid_sender_id400The specified Sender ID is not registered on your account or has not been approved.
insufficient_credits422Your account does not have enough credits to send this message or campaign.
rate_limit_exceeded429You are sending requests too quickly. Implement backoff and retry.
message_too_long400The message body exceeds the maximum allowed character length.
server_error500An internal error occurred. Retry the request or contact support@hany.tools.

Handling Errors

Check the HTTP status code first, then inspect error.code to take the appropriate action in your integration:
const response = await fetch('https://api.hany.tools/v1/sms/send', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.HANY_API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ to: '+233XXXXXXXXX', from: 'YourBrand', message: 'Hello!' })
});

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

  // Handle specific error codes
  if (error.code === 'insufficient_credits') {
    // Redirect user to top up their credits
  } else if (error.code === 'invalid_recipient') {
    // Prompt the user to correct the phone number
  } else if (error.code === 'rate_limit_exceeded') {
    // Back off and schedule a retry
  }
}
When retrying after 429 Too Many Requests or 500 Internal Server Error responses, use exponential backoff — wait 1 second before the first retry, 2 seconds before the second, 4 seconds before the third, and so on. This avoids hammering the API while it recovers and reduces the chance of triggering the rate limit again.