Skip to main content

Send SMS

Send an SMS message to one of your eSIMs. Useful for delivering setup instructions, alerts, or notices directly to the device.

note

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

Open raw .txt

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.

Building the whole integration? Use the complete prompt for all endpoints instead of combining the per-endpoint ones.

Authentication​

This endpoint requires HMAC authentication. See Authentication for details.

Request Headers​

HeaderTypeRequiredDescription
RT-AccessCodeStringYesYour API access code
RT-RequestIDStringYesUnique request ID (UUID v4)
RT-TimestampStringYesRequest timestamp in milliseconds
RT-SignatureStringYesHMAC-SHA256 signature
Content-TypeStringYesMust be "application/json"

Request Body​

Identify the eSIM by iccid (recommended) or esimId.

FieldTypeRequiredDescription
iccidStringYes*The ICCID of the eSIM to message
esimIdIntegerYes*The eSIM id (from the eSIM list/order response). Used if iccid is not provided.
messageStringYesThe 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​

FieldTypeDescription
successBooleanWhether the SMS was sent
messageStringHuman-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.