Calenzy API
APIs/For your website

SMS API

New

Send one SMS from your own system, paid from your Calenzy SMS balance.

/v1/smsNot counted in your quota3 endpointsFrom your server only

Send 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.

Call it from your server, never from a browser or an app: your API key would be public.

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.

POST/v1/sms/send

Send an SMS

One SMS to one number, now.

Query
projectRequiredintegerYour project's ID
Body
toRequiredstringThe phone number, with its country code (+33612345678) or as your customers write it in your country (06 12 34 56 78)
textRequiredstringThe message, up to 3 SMS. See How SMS are counted
labelstringA short title for the person's timeline in Clients, such as Confirmation V611-0007. 120 characters at most
contact_idintegerThe person in Clients, from Add a client. Without it we find them by their number
marketingbooleantrue for an offer: adds the STOP line. See Order messages and offers
Response
statusstringsuccess
sms.idintegerThe SMS's ID, to follow its delivery
sms.tostringThe number we sent to, with its country code
sms.partsintegerHow many SMS it counted for
sms.statusstringpending (handed to the carrier), or skipped on a demo account
balanceobjectWhat is left after this one, as in the balance
Request
POSTapi.calenzy.app/v1/sms/send?project=7
{
  "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"
}
Response · 200 OK
{
  "status": "success",
  "sms": {
    "id": 32762,
    "to": "+33612345678",
    "parts": 1,
    "status": "pending"
  },
  "balance": {
    "sms_left": 99,
    "monthly": 0,
    "packs": 99
  }
}
GET/v1/sms/balance

Get your balance

How many SMS you can still send.

Query
projectRequiredintegerYour project's ID
Response
statusstringsuccess
balance.sms_leftintegerEverything you can still send
balance.monthlyintegerLeft from your plan's allowance this month. It starts again on the day your plan renews each month
balance.packsintegerLeft from the packs you bought. Packs never expire
Request
GETapi.calenzy.app/v1/sms/balance?project=7
Response · 200 OK
{
  "status": "success",
  "balance": {
    "sms_left": 99,
    "monthly": 0,
    "packs": 99
  }
}
GET/v1/sms/{id}

Get an SMS

One SMS you sent here, and whether it arrived.

Path
idRequiredintegerThe sms.id from Send an SMS
Query
projectRequiredintegerYour project's ID
Response
statusstringsuccess
sms.statusstringpending, delivered, failed, or not_sent_quota (your balance was empty)
sms.provider_statusstringThe carrier's own word for it, as it last reported
sms.to, sms.label, sms.text, sms.partsAs sent
sms.contact_idinteger or nullThe person in Clients it is filed under
sms.sent_atstringWhen it was sent, your local time, YYYY-MM-DD HH:MM:SS
Request
GETapi.calenzy.app/v1/sms/32762?project=7
Response · 200 OK
{
  "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.

CodeHTTPWhen
missing_project400project is missing
invalid_phone400to is not a phone number we can send to
sms_text_invalid400text is empty or longer than 3 SMS
sms_quota_exhausted402No SMS left. Nothing was sent. See When your balance is empty
project_not_found404The project does not exist or is not yours
sms_rate_limited429More than 200 SMS in the last hour from your account. Retry later
sms_provider_error502Our SMS carrier did not take it. Nothing was counted: retry in a few minutes
sms_unavailable503SMS are unavailable for a moment. Retry in a few minutes