Network Events
List the recent network events for one of your eSIMs — each time it attached to a network or opened a data session, including when, where, which network it used, the connection type, and whether that network is covered by the plan. Useful for diagnosing "no data" reports and confirming a device is connecting to an allowed network.
Events cover up to the last 7 days and are returned newest-first. Available for eSIMs on networks that report event data.
Endpoint
POST /api/v1/business/esims/network-events
AI prompt — Network Events
Paste into ChatGPT, Claude, Cursor, Copilot or any coding agent to generate this part of your integration. Built-in recommendation: Diagnostic timeline for "no data" tickets; on demand, 5-minute cache, highlight wrong-network events.
Show prompt text (45 lines)
# eSIMfly Business API — Network Events (POST /esims/network-events) — prompt for AI coding assistants
TASK: build a diagnostic view listing the last 7 days of network events (attach / data session) for one
eSIM, highlighting connections to networks NOT covered by the plan. On-demand support tool only —
never in crons or on ordinary page loads.
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/network-events
Body: { "iccid": "8948010010036785060" } or { "esimId": 15757 }
RESPONSE 200
{ success: true, data: { iccid, total_events, wrong_network_count,
events: [{ time (ISO UTC), event_type: "attach"|"data_session"|"location_update"|raw, req_type ("Init"|"Update"|"Term"|"UL"|"ULR"),
operator, mcc, mnc, country, country_iso2, msisdn|null, apn|null, connection_type|null ("4G - LTE","5G"),
data_response|null ("9700: Success 100.00 Mb"), is_allowed: boolean }] } } // newest first, last 7 days
wrong_network_count > 0 (or any is_allowed === false) = the device latched onto a network outside the plan —
the usual cause of "connected but no data". Fix: airplane-mode toggle or manual network selection.
ERRORS: 400 MISSING_IDENTIFIER; 400 NOT_SUPPORTED (eSIM's network does not report events); 403 FORBIDDEN; 404 ESIM_NOT_FOUND.
INTEGRATION PATTERN
1. Support console: "Show network events" button on the eSIM ticket, throttled to 1 call per eSIM per 60 s.
2. Render a timeline; colour rows with is_allowed === false red and show the suggested customer fix.
3. Combine with POST /esims/status (live status) for a complete "no data" diagnosis; do not call either
automatically when the ticket opens — only when the agent asks.
4. Cache the response for 5 minutes per ICCID; empty events list means the eSIM has not connected yet.
5. NOT_SUPPORTED is a normal state for some providers: hide the button, do not error.
DELIVERABLE: getNetworkEvents(iccid) in the shared client with a 5-minute cache and the timeline panel.
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 query |
| esimId | Integer | Yes* | The eSIM id (from the eSIM list/order response). Used if iccid is not provided. |
* Provide either iccid or esimId.
{
"iccid": "8948010010036785060"
}
Response
Success Response (200 OK)
{
"success": true,
"message": "Network events retrieved",
"data": {
"iccid": "8948010010036785060",
"total_events": 2,
"wrong_network_count": 0,
"events": [
{
"time": "2026-06-26T14:08:51",
"event_type": "data_session",
"req_type": "Update",
"operator": "Telenor",
"mcc": "240",
"mnc": "07",
"country": "Sweden",
"country_iso2": "SE",
"msisdn": "48000000000",
"apn": "plus",
"connection_type": "4G - LTE",
"data_response": "9700: Success 100.00 Mb",
"is_allowed": true
},
{
"time": "2026-06-26T13:08:49",
"event_type": "attach",
"req_type": "ULR",
"operator": "Telenor",
"mcc": "240",
"mnc": "07",
"country": "Sweden",
"country_iso2": "SE",
"msisdn": null,
"apn": null,
"connection_type": null,
"data_response": null,
"is_allowed": true
}
]
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
| success | Boolean | Whether the events were retrieved |
| message | String | Human-readable summary |
| data.iccid | String | The ICCID of the eSIM |
| data.total_events | Integer | Number of events returned |
| data.wrong_network_count | Integer | How many events were on a network not covered by the plan |
| data.events | Array | The network events, newest first |
| data.events[].time | String | When the event occurred (ISO 8601, UTC) |
| data.events[].event_type | String | High-level category: attach, data_session, location_update, or the raw type |
| data.events[].req_type | String | Specific request type, e.g. Init, Update, Term (data session) or UL, ULR (attach) |
| data.events[].operator | String | Network operator the eSIM connected to |
| data.events[].mcc | String | Mobile Country Code |
| data.events[].mnc | String | Mobile Network Code |
| data.events[].country | String | Country of the network |
| data.events[].country_iso2 | String | ISO 3166-1 alpha-2 country code |
| data.events[].msisdn | String/null | The profile's home MSISDN (a roaming-hub +48 number for eSIMfly-network eSIMs), present on data-session events |
| data.events[].apn | String/null | Access Point Name used for the data session |
| data.events[].connection_type | String/null | Radio access technology (e.g. 4G - LTE, 5G) |
| data.events[].data_response | String/null | Network response for the data session, including data passed (e.g. 9700: Success 100.00 Mb) |
| data.events[].is_allowed | Boolean | Whether this network is covered by the plan (false = wrong network) |
Error Responses
400 Bad Request
Missing identifier:
{ "success": false, "message": "Provide either iccid or esimId", "code": "MISSING_IDENTIFIER" }
Not supported for this eSIM:
{ "success": false, "message": "Network events are not available for this eSIM", "code": "NOT_SUPPORTED" }
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 getNetworkEvents(iccid) {
const accessCode = 'esf_your_access_code';
const secretKey = 'sk_your_secret_key';
const body = JSON.stringify({ iccid });
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/network-events', {
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(`${data.data.total_events} events, ${data.data.wrong_network_count} on a wrong network`);
} else {
console.error(`Lookup failed: ${data.message}`);
}
return data;
}
Notes
- Events cover up to the last 7 days. If the eSIM has not connected yet, the list is empty.
- A non-empty
wrong_network_countmeans the device latched onto a network outside the plan's coverage — usually the cause of a "connected but no data" report. Toggling airplane mode (or manually selecting an allowed network) typically resolves it. is_allowedis evaluated against every plan currently on the eSIM, including any added later.