OTP, order updates, appointment reminders. Nobody opts out of these — but they fail differently from marketing, and they need to be set up differently.
A promotional blast that arrives twenty minutes late is fine. An OTP that arrives twenty minutes late has already failed — the user gave up, or worse, requested three more and you paid for all four. The two categories share a delivery network and almost nothing else:
| Transactional | Marketing | |
|---|---|---|
| Consent | Implied by the transaction | Explicit opt-in required |
| Timing | Seconds matter | Same day is fine |
| Volume | Unpredictable, event-driven | Planned in advance |
| Sender | Short code, which users trust for OTP | Brand sender ID |
| Failure cost | A user cannot log in | One lost impression |
1. Send from a short code. Users have been trained by banks to expect one-time passwords from 5-digit numeric senders. An OTP from an unfamiliar brand name reads as phishing and gets ignored. Note that recipients cannot reply to our shared short code 66886, and we don't receive replies either — more on short codes.
2. Keep transactional messages clean. No emoji — one converts the message to Unicode and cuts the limit from 156 characters to 66 on our route, which can silently split your OTP into two billed segments. No marketing language attached to an OTP: it undermines the implied consent that made the message legitimate in the first place.
3. Make retries safe. Event-driven sending means your code will retry after a
timeout at some point. If those retries are not idempotent, a checkout hiccup becomes two OTPs and
two charges. Every send through our API accepts an
Idempotency-Key, so a repeated request returns the original result instead of sending
again.
Single-number sends are not queued behind bulk campaigns: a request with three numbers or fewer is passed to the carrier as soon as it is accepted. The full checklist for wiring up OTP is in the OTP section of our API docs; cost, speed and sender details for verification codes are on OTP SMS Malaysia.
Transactional failures are invisible from the inside: the user does not file a support ticket saying "the OTP never came", they just leave. Two things to watch:
Transactional volume follows your business, not a plan — a quiet month should cost less, not the same. Prepaid credit with no monthly fee and no expiry fits that shape better than a subscription sized for your busiest week. Current rates are on the pricing page.
Transactional messages are triggered by something the recipient did — an OTP, an order update, a booking reminder — and consent is implied by that transaction. Promotional messages advertise, and require explicit opt-in under the PDPA. They also differ operationally: transactional traffic is latency-sensitive and unpredictable in volume.
Not separate marketing consent, because the message is part of the service the customer asked for. But the number must still be used only for that purpose — attaching a promotion to an OTP converts it into a marketing message and removes that basis.
The SMS itself usually reaches the phone within seconds on Malaysian networks. The carrier delivery receipt can take from a few minutes to a few hours to come back; until it does, the report shows Processing. If users report waiting minutes or receiving nothing, the usual causes are content filtering or a route problem rather than handset issues — check the per-number delivery report and the gap between submitted and delivered.
Yes, through the REST API. That is the normal setup for transactional messaging, since the trigger is an event in your application rather than a person uploading a list.
If you send an Idempotency-Key header, the second request returns the first result and nothing is sent or charged again. Without it, the second request is treated as a new message. For event-driven sending, always set the header.
RM1 trial credit (claim it on WhatsApp after signing up), a 5-digit short code sender, and a delivery report per number — on day one.