Skip to content
Guides, DLT Template Rejected? Fixes and Samples That Pass (2026)
Guides

DLT Template Rejected? Fixes and Samples That Pass (2026)

RRRavi Rai11 min read

A client rang me last month because their OTPs had stopped arriving. Nothing in their code had changed. The SMS gateway's dashboard showed every message as submitted, then failed, with a one-line reason: template not matched. The template had been approved two years earlier and had worked every day since.

What changed was the rulebook. TRAI's direction of 18 November 2025 made every variable in a DLT template declare a type, and templates written the old way started failing once the grace period ran out. That one change is behind most of the rejection and delivery complaints we've seen this year, but it isn't the only one. This post goes through why DLT templates get rejected at registration, why approved ones still fail when you send them, and gives sample templates that pass today. If you want to test one of your own as you read, paste it into our free DLT template checker.

The short answer: why DLT templates fail

There are two different failures, and people mix them up. A template can be rejected by the operator when you register it, or it can be approved and then blocked when a real message is scrubbed against it. The causes overlap but they aren't the same list.

  • Rejected at registration: an untyped {#var#} slot, more than two variables, two variables touching each other, marketing words on a Service header, no brand name in the text, or a Service Explicit template with no consent template linked to it.
  • Approved but blocked at send time: the sent text differs from the registered text by even a space or a line break, a variable value breaks its type (letters inside {#numeric#}, a 45 character name in {#alphanumeric#}), a link or callback number that isn't whitelisted, the wrong header, or no declared chain between your business and the SMS gateway.

Most of the second list shows up in gateway logs as "template not found", "template ID mismatch" or "DLT scrubbing failed". The wording differs between providers. The cause usually doesn't.

What changed in 2025 and 2026

If your templates were registered before 2025 and you haven't touched them since, assume at least one of these applies to you.

Variable pre-tagging. Every variable now carries a type: {#numeric#} (digits only), {#alphanumeric#} (letters and digits, 40 characters at most), {#url#}, {#urlott#} (app and APK links), {#cbn#} (callback numbers) and {#email#}. The old catch-all {#var#} is not accepted on new templates. New templates had to comply almost straight away, and existing ones got a grace period of about 60 days, during which errors were logged and businesses were told to fix them. After that, non-compliant messages are simply rejected. There is no fallback.

Whitelisting of links and numbers. Since October 2024, any URL, APK or OTT link in an SMS has to be registered on the DLT portal first, and the February 2025 amendment extended the same check to callback numbers. A message containing a link that isn't on your whitelist gets dropped, even if the template itself is fine.

Declared delivery chains. Since December 2024, the path from your business (the Principal Entity) through each telemarketer and aggregator to the operator has to be declared on the portal. If your SMS provider routes through a partner you never bound on DLT, the message fails traceability and goes nowhere.

None of this is hard to fix. It's just that each change landed separately, and many businesses only found out when a batch of messages vanished.

Why a DLT template is rejected when you register it

1. The variables have no type

This is the big one in 2026. Dear {#var#}, your order {#var#} is confirmed will be sent back. Rewrite it as Dear {#alphanumeric#}, your order {#numeric#} is confirmed, choosing the type by what will actually go in the slot. If your order numbers contain letters, like BB-10442, that slot is {#alphanumeric#}, not {#numeric#}. Get this wrong and the template is approved but every real message fails, which is worse than a rejection because you find out later.

2. Too many variables, or variables next to each other

Two variables per template is the normal limit. A third is allowed only with a recorded reason, and some operators reject three by default. The variables also can't touch: {#alphanumeric#} {#numeric#} with only a space, comma or dash between them is refused, because it would let someone stuff arbitrary text into what looks like a fixed message. Put real words between them, or split the message into two templates.

3. Marketing words on a Service or Transactional template

Service Implicit is for messages about something the customer already has: an order, a booking, a bill, a delivery. The moment the text says "flat 20% off", "shop now" or "limited time", the reviewer reads it as promotional and rejects it, or you get it approved and it gets flagged later. Promotional templates have to go on a promotional (numeric) header, and they only reach people who haven't blocked promotions. That's the trade you make.

Transactional is narrower than most people think. It's meant for OTPs and, for banks, transaction alerts. An order confirmation from a shop is Service Implicit, not Transactional.

4. No brand name, or text too vague to review

Reviewers need to be able to tell who the message is from and what it's about. Your code is {#numeric#} often comes back. {#numeric#} is your login OTP for Sharma Dental. Valid for 10 minutes. goes through. Put your business name in the fixed text of every template.

5. Service Explicit without consent

Service Explicit is for messages that need the customer's explicit permission, such as a follow-up offer to an existing customer. The template has to be linked to a consent template, and without that link it's rejected every time. If you don't have a consent flow, you probably want Service Implicit or Promotional instead.

6. A link in the fixed text that isn't whitelisted

If your template contains https://example.in/track as fixed text, that URL has to be on your CTA whitelist before you submit. The same applies to a phone number you ask people to call back on. Register the links first, then the template.

Approved, but "template not found" when you send

This is the one that wastes the most time, because everything looks right on the portal. When a message is sent, the operator's system checks it character by character against the templates registered for that header. If it can't line up the fixed text exactly, it doesn't find a match. The usual reasons:

  • Whitespace and punctuation. A double space, a trailing full stop, a line break where the registered version has a space, or a curly apostrophe (’) instead of a straight one ('). Rich text editors and copy-paste from Word are the usual culprits.
  • The rupee sign. ₹ isn't in the GSM character set, so a message containing it is sent as Unicode. If the template was registered as plain text and your code sends Unicode, or the other way round, it won't match. Most of our clients just write Rs. in SMS and keep ₹ for WhatsApp and email.
  • A value that breaks its type. {#numeric#} receives 1,250.00 with a comma and a decimal point, or a customer's full name runs past 40 characters in {#alphanumeric#}. Format amounts before sending and trim long names.
  • The wrong template ID or header. The API call passes one template ID but the text belongs to another, or the template was registered under header SHRMDN and you're sending from SHRMDL. One template should be tagged to one header.
  • An undeclared chain. Your provider changed its upstream route and the new aggregator isn't bound to your entity. Ask your provider which telemarketers carry your traffic and make sure each is declared on the portal.
  • A link that isn't on the whitelist. Especially short links. If you shorten with a public shortener, the short domain itself has to be whitelisted, and many aren't allowed at all. A short link on your own domain is safer.

The fastest way to find which one it is: take the exact string your code sent (from the provider's logs, not from your source code), put the registered template next to it, and compare them in a diff tool. Nine times out of ten you can see the problem in a minute.

Sample DLT SMS templates that get approved

These are written to pass the 2026 rules: typed variables, two at most, real words between them, a business name in the fixed text, and no characters that force Unicode. Change the business name, keep the structure. Sharma Dental is a made-up example.

OTP (Transactional or Service Implicit, depending on your portal)

text{#numeric#} is your OTP to log in to Sharma Dental. It is valid for 10 minutes. Do not share it with anyone.

Order confirmation (Service Implicit)

textThank you for your order {#alphanumeric#} with Sharma Dental. We will send you an update when it is ready for delivery.

Delivery update with a tracking link (Service Implicit)

textYour Sharma Dental order has been shipped. Track it here: {#url#} - Team Sharma Dental

The domain in that {#url#} slot must be on your whitelist. The template approving doesn't mean the link will.

Payment reminder (Service Implicit)

textDear customer, your Sharma Dental bill of Rs. {#numeric#} is due on {#alphanumeric#}. Please ignore this message if you have already paid.

Appointment reminder with a callback number (Service Implicit)

textReminder: your appointment at Sharma Dental is on {#alphanumeric#}. To reschedule, call us on {#cbn#}.

Offer (Promotional, numeric header only)

textSharma Dental: get 20% off teeth whitening this month. Book at {#url#} T&C apply.

The five service templates run clean through the checker. The offer gets a warning that it reads as promotional, which is the point: it's telling you that text belongs on a promotional header and nowhere else. If you adapt any of them, run your version through it too, because the most common mistake I see is someone adding a second name or date and ending up with three variables.

How long approval takes, and what DLT costs

Template approval usually takes one to three working days, depending on the operator and how busy the queue is. Headers can take a little longer. A rejection resets the clock, which is the real cost of a sloppy template: two days lost on a launch you'd told a client about.

Registering as a Principal Entity costs about ₹5,900 (₹5,000 plus GST) on the first operator's portal, and the registration then works across the others. Templates and headers don't carry a separate charge on most portals. Your SMS provider bills per message on top of that, and some charge a small scrubbing fee per SMS; ask for it in writing before you sign.

How we build SMS so this doesn't break

Most of the failures above are code problems pretending to be compliance problems. The template approved on the portal and the string your app sends are two copies of the same text, maintained by different people, and they drift. So in the NestJS backends we build, there is only one copy.

  1. Each approved template lives in the database with its template ID, header, category and exact registered text, typed tags included.
  2. The app never writes SMS text by hand. It asks for a template by name and passes the values, and the service fills the slots in the registered string.
  3. Before sending, each value is checked against its tag: digits only for {#numeric#}, 40 characters for {#alphanumeric#}, a whitelisted domain for {#url#}. A bad value fails loudly in our logs instead of silently at the operator.
  4. OTPs fall back to WhatsApp or email if the SMS isn't delivered within a set time, so a DLT problem is an alert for us, not a locked-out customer.

It's a day or two of work on a new project and pays for itself the first time a regulation changes. We wrote up the full design in our DLT-compliant notification service architecture, and if you're weighing SMS against WhatsApp for alerts, the WhatsApp Business API guide covers the other side.

OTPs or order alerts failing and you can't tell why? Send us the template, the text your app actually sends and the error from your SMS provider. We'll tell you what's wrong, usually the same day, and fix the sending code if it needs it.

Fix my SMS setup

Frequently asked questions

Why was my DLT template rejected?
The most common reasons in 2026 are untyped {#var#} variables, more than two variables, two variables placed next to each other, promotional wording on a Service or Transactional template, no business name in the text, and a Service Explicit template without a linked consent template. The rejection note on the portal usually points to one of these.
What does "DLT template not found" or "template ID mismatch" mean?
It means the text that was sent could not be matched to a registered template for that header. The usual causes are a small difference in spaces, punctuation or line breaks, a value that breaks its variable type, a Unicode character such as the rupee sign, the wrong template ID or header in the API call, or a non-whitelisted link.
What are the new DLT variable types?
Since TRAI's direction of 18 November 2025, every variable must be one of six types: {#numeric#} for digits, {#alphanumeric#} for letters and digits up to 40 characters, {#url#} for web links, {#urlott#} for app and APK links, {#cbn#} for callback numbers and {#email#} for email addresses. The old {#var#} is not accepted.
How long does DLT template approval take?
Usually one to three working days, depending on the operator. Headers can take slightly longer. A rejected template has to be fixed and resubmitted, which starts the wait again, so it is worth checking a template before you submit it.
How much does DLT registration cost?
Principal Entity registration costs about Rs. 5,900 (Rs. 5,000 plus 18% GST) on the first operator's portal, and that registration is then valid across operators. Templates and headers usually carry no separate charge. Your SMS provider charges per message on top.
Which DLT category should an OTP or order update use?
OTPs go under Transactional where your portal allows it, otherwise Service Implicit. Order confirmations, delivery updates, bills and appointment reminders are Service Implicit, because they are about something the customer already has. Anything with an offer or discount is Promotional and must use a numeric header.
RR
Written by
Ravi Rai

Founder of buildbyravirai, a web development agency based in Noida, India. 5+ years shipping Next.js, WordPress, Shopify, and Laravel projects for clients in India, USA, Canada, and the UK.

You have read the how

Want to know what it costs before you commit to anything?

A guide tells you what is involved. It does not tell you the number. Ours is published: flat pricing, a written scope before any code, and a quote back within 24 hours of the first real conversation.