Indian DLT
Register DLT entities and templates so SMS to +91 destinations is delivered.
Indian DLT
TRAI requires every commercial SMS into India to:
- Be sent under a registered Sender ID (header), tied to a registered Principal Entity.
- Match a registered Template word-for-word — variable placeholders allowed, but the static text must be identical.
TryVox stores your DLT registration metadata so the Messaging API can validate every SMS to +91 against it before egress. Storing a record here does not register you with the DLT operator — you still need to register on Jio TrueConnect / Airtel / VI / BSNL portals first, then mirror the resulting IDs into TryVox.
Lifecycle
1. Register your Principal Entity on a DLT operator portal.
2. Get back: entity_id, sender_ids, template_ids.
3. Mirror them into TryVox via the Compliance API.
4. Send SMS via the Messaging API — sends are validated automatically.Registrations
A registration is the entity record (Principal Entity ID + sender IDs) for a given DLT operator.
Create
POST /v1/compliance/dlt/registrations| Field | Type | Required | Description |
|---|---|---|---|
entity_id | string | yes | Principal Entity ID issued by the DLT operator. |
entity_name | string | yes | Registered legal name. |
dlt_platform | string | yes | jio, airtel, vi, or bsnl. |
sender_ids | string[] | yes | Approved sender IDs (header text), e.g. ["TRYVOX", "TVXOTP"]. |
curl -X POST https://api.tryvox.io/v1/compliance/dlt/registrations \
-u $TRYVOX_AUTH_ID:$TRYVOX_AUTH_TOKEN \
-H "Content-Type: application/json" \
-d '{
"entity_id": "1701000000000012345",
"entity_name": "Tryvox Technologies Pvt Ltd",
"dlt_platform": "jio",
"sender_ids": ["TRYVOX", "TVXOTP"]
}'201 Created returns the full record:
{
"id": "8f7a4b2e-91c2-4f3d-9a1e-2c4b6d8f0a1c",
"entity_id": "1701000000000012345",
"entity_name": "Tryvox Technologies Pvt Ltd",
"dlt_platform": "jio",
"sender_ids": ["TRYVOX", "TVXOTP"],
"status": "active",
"created_at": "2026-04-09T10:30:00Z"
}List
GET /v1/compliance/dlt/registrationsReturns 200 OK with an array of every registration on the tenant.
Get
GET /v1/compliance/dlt/registrations/{id}Update
PUT /v1/compliance/dlt/registrations/{id}PATCH-style: only the fields you submit are applied. Common: appending a new sender_id after the operator approves it.
curl -X PUT https://api.tryvox.io/v1/compliance/dlt/registrations/$REG_ID \
-u $TRYVOX_AUTH_ID:$TRYVOX_AUTH_TOKEN \
-H "Content-Type: application/json" \
-d '{"sender_ids": ["TRYVOX", "TVXOTP", "TVXALR"]}'Delete
DELETE /v1/compliance/dlt/registrations/{id}204 No Content. Deleting a registration also removes any templates that reference it. SMS to +91 will start failing with 403 DLT_NOT_REGISTERED until you create a fresh registration.
Templates
A template is the body text registered with the DLT operator. Outgoing messages must match it word-for-word (placeholders are wildcards).
Create
POST /v1/compliance/dlt/templates| Field | Type | Required | Description |
|---|---|---|---|
registration_id | uuid | yes | The registration this template belongs under. |
template_id | string | yes | Template ID issued by the DLT operator. |
template_name | string | yes | Your label. |
template_body | string | yes | Exact body text as registered. Use {#var#} placeholders for variables (matches the DLT convention). |
template_type | string | yes | transactional, service-implicit, service-explicit, or promotional. |
sender_id | string | yes | Which sender ID from the registration this template uses. |
curl -X POST https://api.tryvox.io/v1/compliance/dlt/templates \
-u $TRYVOX_AUTH_ID:$TRYVOX_AUTH_TOKEN \
-H "Content-Type: application/json" \
-d '{
"registration_id": "8f7a4b2e-91c2-4f3d-9a1e-2c4b6d8f0a1c",
"template_id": "1707000000000054321",
"template_name": "Login OTP",
"template_body": "Your TryVox login code is {#var#}. Valid for 5 minutes. Do not share.",
"template_type": "transactional",
"sender_id": "TVXOTP"
}'201 Created:
{
"id": "1b2c3d4e-5f60-7180-9a2b-3c4d5e6f7a8b",
"registration_id": "8f7a4b2e-91c2-4f3d-9a1e-2c4b6d8f0a1c",
"template_id": "1707000000000054321",
"template_name": "Login OTP",
"template_body": "Your TryVox login code is {#var#}. Valid for 5 minutes. Do not share.",
"template_type": "transactional",
"sender_id": "TVXOTP",
"status": "active",
"created_at": "2026-04-09T10:35:00Z"
}List, Get, Update, Delete
Mirror the registration shape:
GET /v1/compliance/dlt/templates
GET /v1/compliance/dlt/templates/{id}
PUT /v1/compliance/dlt/templates/{id}
DELETE /v1/compliance/dlt/templates/{id}Update lets you change the status (e.g. to disabled if the operator pauses your template), or fix a typo in template_body after re-registering with the operator.
Validation at send time
When the Messaging API processes an SMS to a +91 number it:
- Looks up an active DLT registration for the tenant whose
sender_idsincludes the sender on the send request. - Looks up an active template under that registration whose
template_body(with placeholders treated as wildcards) matches the message text. - If either lookup fails, the send is rejected:
{
"error": {
"code": "DLT_NOT_REGISTERED",
"message": "no DLT template matches this message body for sender 'TVXOTP'",
"details": [
{"field": "sender_id", "reason": "not registered"}
]
}
}The validator runs synchronously before the SMS leaves TryVox — there is no surprise rejection by the operator after the API has accepted the send.
Errors
| Status | Code | Reason |
|---|---|---|
| 400 | VALIDATION_FAILED | Missing required field, malformed JSON |
| 401 | INVALID_CREDENTIALS | Auth ID / Auth Token bad |
| 404 | NOT_FOUND | No registration/template with this id, or it belongs to another tenant |
| 409 | DUPLICATE_ENTITY_ID | Another registration on this tenant already uses this entity_id |
Notes
- One registration per DLT operator is typical, but you can create multiples — useful if you operate under different entities for different brands.
- Disable instead of delete when iterating templates. Deletes are irreversible;
status: "disabled"keeps history while removing the template from validation. - Template body matching is whitespace-tolerant but case-sensitive. Newlines, tabs, and runs of spaces are normalised before comparison.