Success
{
"ok": true
}
ACloudSMS
ACloud SMS API
Server-to-server REST API for virtual SMS numbers: receive messages, inspect numbers, manage senders, check credits and send outbound SMS.
https://app.aharon.cloud/api/v1AuthBearer tokenFormatJSONUse a server access key from your account settings. Never expose this key in frontend code.
curl \
--request GET \
--url "https://app.aharon.cloud/api/v1/messages" \
--header "Authorization: Bearer ACCESS_KEY_HERE" \
--header "Accept: application/json"| Header | Authorization |
|---|---|
| Value | Bearer ACCESS_KEY_HERE |
| Token type | server |
| Failure | 401 missing_bearer_token / 401 invalid_token |
{
"ok": true
}{
"ok": false,
"error": "invalid_token",
"message": "Bad request"
}| Status | Error | Meaning |
|---|---|---|
| 400 | bad_request, missing_sender | Invalid input or missing field. |
| 401 | missing_bearer_token, invalid_token | Token is missing, revoked or invalid. |
| 402 | insufficient_credits | Not enough sending credits. |
| 423 | sms_sending_closed_weekend | Sending is closed in the configured weekend window. |
| 429 | too_many_recipients | Too many recipients or rate limit. |
| 502 | provider_send_failed | SMS provider returned a failure. |
| 503 | sms_sending_not_enabled | Sending is disabled. |
Returns the authenticated account and current SMS credit balance.
{
"ok": true,
"user": {
"id": 123,
"email": "customer@example.com",
"token_id": 77,
"token_type": "server",
"sms_credits": 1000
}
}Lists virtual numbers assigned to the authenticated account.
{
"ok": true,
"numbers": [
{
"id": 12,
"number_raw": "0500000000",
"label": "Main",
"status": "assigned"
}
]
}Returns up to limit inbound messages in ascending id order. Use after_id to return only messages with a greater id.
| Query | Required | Notes |
|---|---|---|
limit | No | Integer from 1 to 250. Default: 100. |
after_id | No | Returns only messages whose id is greater than this positive integer. |
virtual_number_id | No | Filters messages by an assigned virtual number id. |
| Field | Type | Description |
|---|---|---|
id | number | Message id. |
virtual_number_id | number | Receiving number id. |
from_raw | string | Original sender. |
to_raw | string | Destination number. |
body | string | Message body. |
provider_received_at | datetime | Provider receive time. |
first_seen_at | datetime | First import time in ACloud. |
Datetime values use YYYY-MM-DD HH:mm:ss without a numeric offset and represent Asia/Jerusalem wall-clock time.
{
"ok": true,
"messages": [
{
"id": 991,
"virtual_number_id": 12,
"from_raw": "Google",
"from_normalized": "Google",
"from_type": "text",
"to_raw": "0500000000",
"body": "Your code is 123456",
"provider_received_at": "2026-07-05 13:45:00",
"first_seen_at": "2026-07-05 13:45:02"
}
],
"pagination": {
"limit": 100,
"count": 1,
"after_id": null,
"next_after_id": 991,
"has_more": false
}
}
Returns one inbound message by id if it belongs to the authenticated account.
| Path | id — required message id. |
|---|
{
"ok": true,
"message": {
"id": 991,
"virtual_number_id": 12,
"from_raw": "Google",
"body": "Your code is 123456"
}
}{
"ok": false,
"error": "not_found"
}Returns the current outbound SMS credit balance.
{
"ok": true,
"sms_credits": 1000
}Marks a sender as spam or blocked.
| Body | Required | Notes |
|---|---|---|
sender / from | Yes | Sender identifier. |
state | No | spam / blocked. Defaults to spam when omitted. |
virtual_number_id | No | Optional number scope. |
{
"sender": "0520000000",
"state": "spam",
"virtual_number_id": 12
}{
"ok": true,
"state": "spam",
"result": {
"state": "spam"
}
}Shortcut endpoint for blocking a sender.
{
"sender": "0520000000",
"virtual_number_id": 12
}{
"ok": true,
"blocked": true,
"result": {
"state": "blocked"
}
}Sends SMS from an assigned virtual number. Billing is calculated by recipients and message segments.
| Body | Required | Notes |
|---|---|---|
from | Yes | Assigned sender number. |
message | Yes | SMS text. |
phones / to | Yes | Recipients separated by colon, comma or newline. |
flash | No | Boolean alias: flash/sendFlashMessage/send_flash. |
curl \
--request POST \
--url "https://app.aharon.cloud/api/v1/sms/send" \
--header "Authorization: Bearer ACCESS_KEY_HERE" \
--header "Content-Type: application/json" \
--data '{
"from": "0500000000",
"to": "0520000000",
"message": "Your code is 123456"
}'{
"ok": true,
"sms": {
"outbound_message_id": 456,
"provider_status": "OK",
"recipients_count": 1,
"segments": 1,
"credits_used": 1,
"balance_after": 999,
"flash": false
}
}Incoming-message webhooks are registered manually per number. ACloud does not expose webhook registration or deletion API endpoints.
There is no event selector. ACloud sends the sms.received event for each incoming SMS.
{
"event": "sms.received",
"message_id": "msg_991",
"number_id": "num_12",
"to": "0500000000",
"from": "Google",
"from_type": "text",
"body": "Your code is 123456",
"received_at": "2026-07-05 13:45:00"
}
received_at uses YYYY-MM-DD HH:mm:ss without a numeric offset and represents Asia/Jerusalem wall-clock time.
X-SMS-Timestamp: 1782395100
X-SMS-Signature: sha256=...
HMAC_SHA256(webhook_secret, timestamp + "." + rawBody)
curl \
--request GET \
--url "https://app.aharon.cloud/api/v1/messages" \
--header "Authorization: Bearer ACCESS_KEY_HERE" \
--header "Accept: application/json"const response = await fetch('https://app.aharon.cloud/api/v1/messages', {
method: 'GET',
headers: {
Authorization: 'Bearer ACCESS_KEY_HERE',
Accept: 'application/json'
}
});
const data = await response.json();
console.log(data);import requests
response = requests.get(
'https://app.aharon.cloud/api/v1/messages',
headers={
'Authorization': 'Bearer ACCESS_KEY_HERE',
'Accept': 'application/json'
},
timeout=20
)
print(response.json())