Set up Exotel
Send SMS (v1), JSON with .json or XML without it. smsyra answers exactly as Exotel would, keeps the text in your inbox, checks it against your DLT templates — and sends nothing.
What to change
https://api.shriradhatechnologies.com/p/exotel/v1/Accounts/YOUR_ACCOUNT_SID/Sms/send.json- Method
- POST
- Your key goes in
- the Basic-auth password
- Instead of
https://api.exotel.com/v1/Accounts/{sid}/Sms/send.json
- Swap https://api.exotel.com (or api.in.exotel.com) for the smsyra host, keeping /v1/Accounts/<sid>/Sms/send.json after /p/exotel.
- Put your smsyra key where your Exotel api_token goes (the Basic-auth password). The user and the AccountSid are echoed, never checked.
- Keep sending DltEntityId and DltTemplateId: smsyra checks the text against the template id.
Need a key? Create a free workspace and make one on its API keys page — it starts with smy_.
Send a test text
curl -X POST "https://api.shriradhatechnologies.com/p/exotel/v1/Accounts/YOUR_ACCOUNT_SID/Sms/send.json" \
-u "YOUR_API_KEY:smy_YOUR_KEY" \
--data-urlencode "From=ACMEOT" \
--data-urlencode "To=9876543210" \
--data-urlencode "Body=482913 is your ACME login code. It is valid for 10 minutes." \
--data-urlencode "DltEntityId=1001234567890123456" \
--data-urlencode "DltTemplateId=1007123456789012345"What smsyra answers
The same status and body Exotel gives when it takes a text (HTTP 200), so your code carries on as it would in production:
{"SMSMessage":{"Sid":"0f2b8c…","AccountSid":"YOUR_ACCOUNT_SID","From":"ACMEOT","To":"+919876543210","Body":"482913 is your ACME login code. It is valid for 10 minutes.","Status":"queued","DetailedStatus":"PENDING_TO_OPERATOR",…}}The text itself shows up in your inbox the moment it arrives, with the DLT result: Matched, Mismatched (with the first character that differs), or No template.
Test the failures
Each API key has a failure mode, so you can test your retries and error handling without breaking anything. More about failure modes.
| When | smsyra answers |
|---|---|
| A key that is unknown or revokedYour provider's authentication error. Nothing is kept. | HTTP 401{"RestException":{"Status":401,"Code":"UNAUTHORIZED","Message":"Authentication failed. Invalid API Key or Token."}} |
| Failure mode: Provider errorThe provider's own error. The text is kept as “Simulated error”. | HTTP 500{"RestException":{"Status":500,"Code":"INTERNAL_SERVER_ERROR","Message":"Internal server error. Please try again later."}} |
| Failure mode: Provider downA 503, as if the provider were down. The text is kept as “Simulated outage”. | HTTP 503{"RestException":{"Status":503,"Code":"SERVICE_UNAVAILABLE","Message":"Service temporarily unavailable. Please try again later."}} |
| Failure mode: SlowWaits as long as you set (up to 30 seconds), then answers normally. | The normal answer (HTTP 200), after the wait. |
| Strict DLT on, and the text doesn't matchRefused the way the provider refuses a DLT failure. The text is kept as “Refused (strict DLT)”. | HTTP 400{"RestException":{"Status":400,"Code":"INVALID_DLT_TEMPLATE","Message":"Invalid DltTemplateId. Template not found or not approved."}} |
Read the OTP in your tests
Ask for the newest code sent to a number. The call waits up to 30 seconds for the text to arrive, so a test never sleeps and polls. It takes your key as Authorization: Bearer smy_…, whichever provider sent the text. The OTP API in full.
curl -G "https://api.shriradhatechnologies.com/v1/otp/latest" \
-H "Authorization: Bearer smy_YOUR_KEY" \
--data-urlencode "to=9876543210" \
--data-urlencode "wait=25"It answers HTTP 200 with the code, or 404 NO_MESSAGE after the wait:
{"messageId":"0193…","to":"+919876543210","from":"ACMEOT","body":"482913 is your ACME login code. It is valid for 10 minutes.","code":"482913","codeMethod":"template","candidates":["482913"],"receivedAt":"2026-11-15T10:20:30Z","templateId":"1007123456789012345","dlt":{"status":"MATCHED"}}Other providers
AmazeSMS · MSG91 (Flow v5) · Fast2SMS · Twilio · smsyra JSON