SMS API
NewSend one SMS from your own system, paid from your Calenzy SMS balance.
/v1/smsNot counted in your quota3 endpointsFrom your server onlySend an SMS when something happens on your side: an order is confirmed, a pickup is today, an appointment moved. Each SMS comes off your Calenzy SMS balance, the month's allowance first, then your packs. Buy packs in Calenzy, Campaigns, Settings.
Every SMS sent here shows on the person's timeline in Clients, with your label, and counts in the usage bar in Campaigns, Settings. Your customers see it from CALENZY.
When your balance is empty
We answer 402 with sms_quota_exhausted and send nothing. It is not an outage: carry on without SMS, and tell your team to top up. Ask the balance to show it in your own screens.
How SMS are counted
One SMS holds 160 plain characters. A longer text goes in parts of 153, and each part counts as one SMS. Some characters switch the whole text to 70 per SMS: emoji, and accents outside the SMS alphabet such as ê, â, î, ô or û (é, è, à, ù and ç are fine). A text can be 3 SMS at most.
Order messages and offers
By default an SMS is a service message (an order, a pickup, an appointment) and carries no STOP line. For an offer or any marketing, send marketing: true: we add the STOP line the law asks for. Send offers only to people who agreed to receive them: Add a client records that answer.
Send an SMS
One SMS to one number, now.
| projectRequiredinteger | Your project's ID |
| toRequiredstring | The phone number, with its country code (+33612345678) or as your customers write it in your country (06 12 34 56 78) |
| textRequiredstring | The message, up to 3 SMS. See How SMS are counted |
| labelstring | A short title for the person's timeline in Clients, such as Confirmation V611-0007. 120 characters at most |
| contact_idinteger | The person in Clients, from Add a client. Without it we find them by their number |
| marketingboolean | true for an offer: adds the STOP line. See Order messages and offers |
| statusstring | success |
| sms.idinteger | The SMS's ID, to follow its delivery |
| sms.tostring | The number we sent to, with its country code |
| sms.partsinteger | How many SMS it counted for |
| sms.statusstring | pending (handed to the carrier), or skipped on a demo account |
| balanceobject | What is left after this one, as in the balance |
{ "to": "06 12 34 56 78", "text": "Le Fournil d'Aspremont : commande V611-0007 confirmée pour ven. 6 nov., 13h-14h.", "label": "Confirmation V611-0007" }
curl -X POST "https://api.calenzy.app/v1/sms/send?project=7" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "06 12 34 56 78",
"text": "Le Fournil d'Aspremont : commande V611-0007 confirmée pour ven. 6 nov., 13h-14h.",
"label": "Confirmation V611-0007"
}'{ "status": "success", "sms": { "id": 32762, "to": "+33612345678", "parts": 1, "status": "pending" }, "balance": { "sms_left": 99, "monthly": 0, "packs": 99 } }
Get your balance
How many SMS you can still send.
| projectRequiredinteger | Your project's ID |
| statusstring | success |
| balance.sms_leftinteger | Everything you can still send |
| balance.monthlyinteger | Left from your plan's allowance this month. It starts again on the day your plan renews each month |
| balance.packsinteger | Left from the packs you bought. Packs never expire |
curl "https://api.calenzy.app/v1/sms/balance?project=7" \ -H "Authorization: Bearer YOUR_API_KEY"
{ "status": "success", "balance": { "sms_left": 99, "monthly": 0, "packs": 99 } }
Get an SMS
One SMS you sent here, and whether it arrived.
| idRequiredinteger | The sms.id from Send an SMS |
| projectRequiredinteger | Your project's ID |
| statusstring | success |
| sms.statusstring | pending, delivered, failed, or not_sent_quota (your balance was empty) |
| sms.provider_statusstring | The carrier's own word for it, as it last reported |
| sms.to, sms.label, sms.text, sms.parts | As sent |
| sms.contact_idinteger or null | The person in Clients it is filed under |
| sms.sent_atstring | When it was sent, your local time, YYYY-MM-DD HH:MM:SS |
curl "https://api.calenzy.app/v1/sms/32762?project=7" \ -H "Authorization: Bearer YOUR_API_KEY"
{ "status": "success", "sms": { "id": 32762, "to": "+33612345678", "label": "Confirmation V611-0007", "text": "Le Fournil d'Aspremont : commande V611-0007 confirmée pour ven. 6 nov., 13h-14h.", "contact_id": 1234, "parts": 1, "status": "delivered", "provider_status": "delivered", "sent_at": "2026-11-05 09:12:03" } }
Errors
Besides these, any call can answer one of the common errors.
| Code | HTTP | When |
|---|---|---|
missing_project | 400 | project is missing |
invalid_phone | 400 | to is not a phone number we can send to |
sms_text_invalid | 400 | text is empty or longer than 3 SMS |
sms_quota_exhausted | 402 | No SMS left. Nothing was sent. See When your balance is empty |
project_not_found | 404 | The project does not exist or is not yours |
sms_rate_limited | 429 | More than 200 SMS in the last hour from your account. Retry later |
sms_provider_error | 502 | Our SMS carrier did not take it. Nothing was counted: retry in a few minutes |
sms_unavailable | 503 | SMS are unavailable for a moment. Retry in a few minutes |