Start one SMS request per documented interval for the number type while leaving carrier delivery timing to the platform.
sms
The claim
The rate limits page, https://signalwire.com/docs/platform/rate-limits, gives messaging throughput per number type. 10DLC is “4 MPS”, toll-free is “3 messages per second (MPS)“, short codes are “10 MPS”, and the queue holds “10,000 queued messages”. Past the rate, SignalWire queues messages in the order received. Once the backlog is full, “SignalWire will stop adding to the Messaging queue”. So sending faster than the rate buys nothing, and a burst large enough to fill the queue loses what did not fit. You send one message per interval instead, so the queue never builds. Each message is a POST /api/messaging/messages with to, from and body, the vendored REST spec’s two required fields and the text.
How it works
LIMITS = {"10dlc": 4, "toll-free": 3, "short-code": 10} # messages per second
BACKLOG = 10_000
def send_batch(recipients, body, number_type=NUMBER_TYPE, clock=time.monotonic, sleep=time.sleep):
if len(recipients) > BACKLOG:
raise ValueError(...)
interval = 1 / LIMITS[number_type]
next_at = clock()
for to in recipients:
now = clock()
if now < next_at:
sleep(next_at - now)
results.append(http.post("/api/messaging/messages", body={"to": to, "from": FROM, "body": body}))
next_at = max(now, next_at) + interval
What the platform receives, once per recipient, a quarter of a second apart on a 10DLC number:
POST /api/messaging/messages
{"to": "+1555YYYYYYY", "from": "+1555XXXXXXX", "body": "Your bike is ready for pickup."}
next_at moves forward by the interval from the later of now and the previous slot. The clock is read again after a sleep, so a sleep that overshoots pushes the next slot out instead of letting two sends land close together. A slow response does not let the next send catch up in a burst either. The clock and the sleep are arguments, so the verifier can run the pacer against a fake clock.
Limitations
You prove the pacing and the requests against a fake clock. The rates are the page’s published figures, and the page says actual 10DLC throughput “may be lower or higher depending on carrier and TCR limits”. Delivery is the platform’s and the carriers’ side.
You run one pacer per number. Two processes sending from the same number each pace themselves and together exceed the rate; put the batch behind one queue.
What to change first
Change the 10DLC rate in LIMITS to 5 and run the verifier. The first assertion fails, because the verifier carries the page’s numbers itself. The platform’s limit does not move when yours does.