Send SMS
Send an SMS message to one of your eSIMs. Useful for delivering setup instructions, alerts, or notices directly to the device.
SMS is supported on most eSIMs but not all. If the eSIM's network does not support messaging, the request returns SMS_NOT_SUPPORTED.
Endpoint
POST /api/v1/business/esims/send-sms
AI prompt — Send SMS
Paste into ChatGPT, Claude, Cursor, Copilot or any coding agent to generate this part of your integration. Built-in recommendation: Transactional messages through a queue; flag eSIMs that return SMS_NOT_SUPPORTED.
Show prompt text (42 lines)
# eSIMfly Business API — Send SMS (POST /esims/send-sms) — prompt for AI coding assistants
TASK: send a short text message to the device holding one of our eSIMs (setup instructions, alerts,
notices). Event-driven, one call per message; not every eSIM supports SMS.
COMMON RULES (apply to every eSIMfly request)
- Base URL: https://esimfly.net/api/v1/business
- Headers on every call: RT-AccessCode (esf_...), RT-RequestID (fresh UUID v4 per request; reuse -> 400 DUPLICATE_REQUEST),
RT-Timestamp (ms since epoch; >5 min old -> 401 INVALID_TIMESTAMP),
RT-Signature = UPPERCASE hex HMAC-SHA256(secretKey, timestamp + requestId + accessCode + rawBody).
rawBody = "" for GET; for POST/PUT sign the exact body string you send, with Content-Type: application/json.
- Keep access code + secret key server-side in env vars. Never ship them to a browser or mobile app.
- Responses: { success: true, ... } or { success: false, error|message, code }. Branch on `success` and `code`.
- Rate limits are per API key, shown in the business dashboard (typically 100/minute, 1,000/hour, 10,000/day) -> RATE_LIMIT_EXCEEDED. Pace bulk work at <= 1 req/s.
- Read `currency` from responses (USD | IQD | EUR for enterprise). Never hard-code it. IQD amounts are integers.
- Package codes are opaque strings: store and send back verbatim, never parse or prefix them.
- Node.js/TypeScript: use the official SDK instead of raw HTTP — `npm install @esimfly/sdk`
(https://github.com/eSimfly-Official/esimfly-sdk-nodejs); it implements these rules. Other languages: implement the contract below.
- Full multi-endpoint prompt: https://docs.esimfly.net/llm/esimfly-api-full-prompt.txt
ENDPOINT
POST https://esimfly.net/api/v1/business/esims/send-sms
Body: { "iccid": "8948010010036785060", "message": "Welcome! Your eSIM is ready to use." } // esimId may replace iccid
message: required, max 500 characters (long texts may be split by the network).
RESPONSE 200: { "success": true, "message": "SMS sent successfully" }
ERRORS: 400 MISSING_IDENTIFIER | MISSING_MESSAGE | MESSAGE_TOO_LONG | SMS_NOT_SUPPORTED (this eSIM's network
cannot receive SMS — treat as a capability, not a failure) | SMS_FAILED (delivery failed); 403 FORBIDDEN; 404 ESIM_NOT_FOUND.
INTEGRATION PATTERN
1. Use for transactional events only: after activation, at 80% data used, before expiry, support replies.
Do not use it for marketing blasts across the fleet.
2. Validate length (<= 500) client-side; keep messages plain text.
3. Record every send on our side (iccid, template, timestamp, result) — eSIMfly also logs it on the order.
4. If a send returns SMS_NOT_SUPPORTED, flag the eSIM `sms_supported = false` locally and stop offering SMS for it.
5. On SMS_FAILED or a timeout, retry at most once after 30 s with a new RT-RequestID; then give up and log.
6. Rate: keep well below your per-minute limit (typically 100) if a batch of notifications fires at once — queue them.
DELIVERABLE: sendSms(iccid, message) in the shared client, a queued notification sender with per-eSIM
capability flag, and the local send log.
Authentication
This endpoint requires HMAC authentication. See Authentication for details.
Request Headers
| Header | Type | Required | Description |
|---|---|---|---|
| RT-AccessCode | String | Yes | Your API access code |
| RT-RequestID | String | Yes | Unique request ID (UUID v4) |
| RT-Timestamp | String | Yes | Request timestamp in milliseconds |
| RT-Signature | String | Yes | HMAC-SHA256 signature |
| Content-Type | String | Yes | Must be "application/json" |
Request Body
Identify the eSIM by iccid (recommended) or esimId.
| Field | Type | Required | Description |
|---|---|---|---|
| iccid | String | Yes* | The ICCID of the eSIM to message |
| esimId | Integer | Yes* | The eSIM id (from the eSIM list/order response). Used if iccid is not provided. |
| message | String | Yes | The SMS text. Max 500 characters. |
* Provide either iccid or esimId.
{
"iccid": "8948010010036785060",
"message": "Welcome! Your eSIM is ready to use."
}
Response
Success Response (200 OK)
{
"success": true,
"message": "SMS sent successfully"
}
Response Fields
| Field | Type | Description |
|---|---|---|
| success | Boolean | Whether the SMS was sent |
| message | String | Human-readable result |
Error Responses
400 Bad Request
Missing identifier:
{ "success": false, "message": "Provide either iccid or esimId", "code": "MISSING_IDENTIFIER" }
Missing message:
{ "success": false, "message": "Message is required", "code": "MISSING_MESSAGE" }
Message too long:
{ "success": false, "message": "Message cannot exceed 500 characters", "code": "MESSAGE_TOO_LONG" }
SMS not supported for this eSIM:
{ "success": false, "message": "SMS is not supported for this eSIM", "code": "SMS_NOT_SUPPORTED" }
Delivery failed:
{ "success": false, "message": "Failed to send SMS", "code": "SMS_FAILED" }
403 Forbidden
eSIM does not belong to your account:
{ "success": false, "message": "You do not have permission to access this eSIM", "code": "FORBIDDEN" }
404 Not Found
{ "success": false, "message": "eSIM not found", "code": "ESIM_NOT_FOUND" }
Example
const crypto = require('crypto');
const { v4: uuidv4 } = require('uuid');
async function sendSms(iccid, message) {
const accessCode = 'esf_your_access_code';
const secretKey = 'sk_your_secret_key';
const body = JSON.stringify({ iccid, message });
const timestamp = Date.now().toString();
const requestId = uuidv4();
const signData = timestamp + requestId + accessCode + body;
const signature = crypto.createHmac('sha256', secretKey)
.update(signData)
.digest('hex')
.toUpperCase();
const response = await fetch('https://esimfly.net/api/v1/business/esims/send-sms', {
method: 'POST',
headers: {
'RT-AccessCode': accessCode,
'RT-RequestID': requestId,
'RT-Timestamp': timestamp,
'RT-Signature': signature,
'Content-Type': 'application/json'
},
body
});
const data = await response.json();
if (data.success) {
console.log('SMS sent');
} else {
console.error(`SMS failed: ${data.message}`);
}
return data;
}
Notes
- The message is delivered to the eSIM's device; it does not appear in any dashboard.
- Maximum length is 500 characters. Long messages may be split into multiple SMS by the network.
- Every send (success or failure) is recorded against the order for your audit trail.