> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hany.tools/llms.txt
> Use this file to discover all available pages before exploring further.

# Send SMS Messages with Hany: Single and Bulk API Guide

> Send single or multiple SMS messages using the Hany API. Includes request examples in cURL, JavaScript, and Python with full response details.

The Hany SMS API gives you a simple, reliable way to send messages to any phone number — whether you're triggering a single OTP from your backend or dispatching transactional alerts in real time. All requests authenticate with your Bearer API key and follow standard REST conventions.

## Send a Single SMS

Make a `POST` request to `/v1/sms/send` with your recipient, Sender ID, and message body.

```bash theme={null}
curl -X POST https://api.hany.tools/v1/sms/send \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+233XXXXXXXXX",
    "from": "YourBrand",
    "message": "Hello! Your order has been shipped."
  }'
```

**Successful response:**

```json theme={null}
{
  "status": "success",
  "message_id": "msg_abc123",
  "to": "+233XXXXXXXXX",
  "from": "YourBrand",
  "credits_used": 1,
  "credits_remaining": 4999
}
```

## Request Parameters

<ParamField body="to" type="string" required>
  The recipient's phone number in **E.164 format** (e.g. `+233XXXXXXXXX`). Always include the country code prefixed with `+`. Do not use spaces, dashes, or parentheses.
</ParamField>

<ParamField body="from" type="string" required>
  Your registered and approved Sender ID (e.g. `YourBrand`). The Sender ID must exist in your account with `approved` status before use.
</ParamField>

<ParamField body="message" type="string" required>
  The text content of your SMS. Standard messages support up to **160 characters per segment**. Messages longer than 160 characters are automatically split into multiple segments and charged accordingly.
</ParamField>

<ParamField body="callback_url" type="string">
  An optional HTTPS URL on your server where Hany will `POST` delivery status updates (webhooks). Use this to track whether a message was delivered, failed, or is still pending.
</ParamField>

## Message Length and Segments

Understanding segments helps you control costs and message formatting:

* **Standard SMS** — Up to **160 characters** per segment. A 160-character message uses 1 credit.
* **Long SMS** — Messages over 160 characters are split into segments of up to **153 characters** each (the remaining characters carry concatenation headers). A 300-character message uses 2 credits.
* **Unicode SMS** — Messages containing Unicode characters (e.g. emojis, Arabic, Chinese) are limited to **70 characters** per segment, or **67 characters** per segment for multi-part Unicode messages.
* **Credits charged per segment** — Each segment consumes 1 credit (GHS 0.02). Keep messages concise to stay efficient.

<Note>
  Always use E.164 format for phone numbers: a `+` sign followed by the country code and subscriber number with no spaces or separators. For Ghana, this looks like `+233XXXXXXXXX`.
</Note>

## Code Examples

<CodeGroup>
  ```javascript JavaScript theme={null}
  const response = await fetch("https://api.hany.tools/v1/sms/send", {
    method: "POST",
    headers: {
      "Authorization": "Bearer YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      to: "+233XXXXXXXXX",
      from: "YourBrand",
      message: "Hello! Your order has been shipped.",
    }),
  });

  const data = await response.json();
  console.log(data);
  ```

  ```python Python theme={null}
  import requests

  url = "https://api.hany.tools/v1/sms/send"
  headers = {
      "Authorization": "Bearer YOUR_API_KEY",
      "Content-Type": "application/json",
  }
  payload = {
      "to": "+233XXXXXXXXX",
      "from": "YourBrand",
      "message": "Hello! Your order has been shipped.",
  }

  response = requests.post(url, json=payload, headers=headers)
  print(response.json())
  ```
</CodeGroup>

## Response Fields

<ResponseField name="status" type="string">
  The result of the request. `"success"` indicates the message was accepted and queued for delivery. On failure, this will be `"error"` and an `error` field will describe the issue.
</ResponseField>

<ResponseField name="message_id" type="string">
  A unique identifier for this message (e.g. `msg_abc123`). Use this ID to look up delivery status or reference the message in support queries.
</ResponseField>

<ResponseField name="to" type="string">
  The recipient phone number as provided in the request, in E.164 format.
</ResponseField>

<ResponseField name="from" type="string">
  The Sender ID used for this message, as provided in the request.
</ResponseField>

<ResponseField name="credits_used" type="integer">
  The number of credits deducted for this message. This equals the number of SMS segments the message was split into.
</ResponseField>

<ResponseField name="credits_remaining" type="integer">
  Your remaining credit balance after this message was sent. Monitor this field to avoid running low before a critical send.
</ResponseField>
