Order updates, alerts, reminders and codes, sent through routes chosen for delivery rather than the cheapest line on a rate card. Every message records the carrier, the reason it was chosen and what it cost.
Each message carries the carrier it went through, the score that carrier had at the time and the cost. It is in the API response and in your logs.
Optimise a message for conversion, cost or speed and cap what it may cost. A route outside the cap is refused, not quietly substituted.
STOP and its local equivalents are honoured automatically per country. A recipient who opts out is suppressed on your account without you writing any code.
Where a country requires registration, Woyra files it and tells you when it is live. Where it does not, your name works from the first send.
The same key works on every country endpoint; which one you call sets the rules and the currency.
curl -X POST https://api.woyra.io/v1/messages \
-H "Authorization: Bearer $WOYRA_KEY" \
-H 'Idempotency-Key: order-4821' \
-H 'Content-Type: application/json' \
-d '{
"channel": "sms",
"to": "+254712345678",
"from": "YOURBRAND",
"body": "Your order 4821 is out for delivery.",
"routing": {"strategy": "conversion_optimized", "max_cost_usd": 0.03}
}'Reference price: Twilio $0.0079 to 0.0083. Full list on the pricing page.
$0.0069 per segment in the United States, plus carrier surcharges passed through at cost. African countries are priced individually and published on their country pages, because one number across the continent would be a fiction.
In countries that allow alphanumeric sender IDs, yes. Some require the name to be registered first; Woyra handles the registration. Others allow only numeric senders, and the country page says which.
Poll the message, or register a webhook and receive message.delivered and message.undelivered events, signed with HMAC-SHA256 and retried until your endpoint acknowledges them.
The router scores carriers continuously and moves traffic away from one that is failing. A message that cannot be carried within your constraints is refused with route_unavailable rather than queued indefinitely.
Each market has its own rules, currency and endpoint. Pick yours.