Send one SMS
Keep the key in an environment variable so it never ends up in your repository. The function returns the data part of the reply, or raises an error with the reason.
import os
import requests
API = "https://avcsms.lk/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['AVCSMS_API_KEY']}"}
def send_sms(to, message, **extra):
r = requests.post(
f"{API}/sms/send",
headers=HEADERS,
json={"to": to, "message": message, **extra},
timeout=30,
)
reply = r.json()
if r.status_code != 201:
raise RuntimeError(reply.get("message", f"SMS request failed (HTTP {r.status_code})"))
return reply["data"]
result = send_sms("0771234567", "Your order #1042 is ready for pick-up.")
print(result["messages"][0]["id"]) # keep this ID to check delivery laterA successful reply has HTTP status 201 and gives the cost, the number of parts, your new balance and an ID for each message. Numbers can be written as 0771234567, 94771234567 or +94771234567.
Send to many numbers, with names
Pass a list to send the same text to every number, up to 10,000 in one request. For a personal greeting, pass name-and-number pairs and write {name} in the message.
result = send_sms(
[
{"to": "0771234567", "name": "Nimal"},
{"to": "0712345678", "name": "Kumari"},
],
"Hi {name}, your November invoice is ready.",
sender_id="MYSHOP",
ref="invoice-nov",
)
print(f"Accepted {result['accepted']} messages, cost Rs. {result['cost']}")The optional fields are sender_id (an approved sender ID on your account), ref (your own reference, returned in status replies), schedule_at (a date and time in Sri Lanka time, such as 2026-12-01 09:30) and callback_url (where the delivery report should go).
Sinhala and Tamil
Python strings are Unicode, so there is nothing special to do. Sinhala and Tamil text is detected by the API and sent as Unicode, with 70 characters per part.
result = send_sms("0771234567", "ඔබේ ඇණවුම සූදානම්. අදම ලබා ගන්න!")
print(result["type"], result["segments"]) # unicode 1Check whether a message was delivered
def sms_status(message_id):
r = requests.get(f"{API}/sms/{message_id}", headers=HEADERS, timeout=30)
r.raise_for_status()
return r.json()["data"]
print(sms_status(9001)["status"]) # queued, sending, sent, delivered or failedReceive delivery reports with Flask
Set a webhook URL on the Developer / API page, or pass callback_url with a send. When a message is delivered or fails, your route receives a JSON report.
from flask import Flask, request
app = Flask(__name__)
@app.post("/sms-status")
def sms_status_report():
report = request.get_json(force=True)
if report.get("event") == "sms.status":
# report["id"], report["ref"], report["to"], report["status"]
# update the order or login record that matches the reference
pass
return "", 200Every endpoint and field is in the SMS API reference. For scripts that send alerts on a schedule, check your balance first with the balance endpoint so a low balance never surprises you.