> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sakawave.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Installation and device support

> What an activation code is, why a QR cannot be scanned from the screen showing it, and how to treat the credential.

Everything else in this API ends when money moves. An eSIM ends when a person successfully installs a profile on a handset — which is a step you cannot perform, cannot verify directly, and can very easily make harder than it needs to be.

## What you are actually handing over

One string. Everything else is a way of getting that string into a phone.

```
LPA:1$smdp.example.com$K2-1A2B3C4D5E
    │ │                │
    │ │                └── matching ID: this profile, once
    │ └── SM-DP+ server: where the phone downloads it from
    └── LPA scheme version
```

The [installation endpoint](/api-reference/esim/get-install-details) returns it three ways, and they are the same credential in different clothing:

| Field | What it is |
| - | - |
| `universalLinkUrl` | A link that opens the phone's own eSIM installer with the details filled in |
| `qrCodePayload` | The LPA string, for you to render as a QR |
| `manual.smdpAddress` + `manual.activationCode` | The two halves, split out for typing |

## Offer them in this order

1. **Universal link.** One tap. Nothing to scan, nothing to type, no second device. Works on iOS 17.4+ and recent Android.
2. **QR code.** Universally understood, but needs a second device — see below.
3. **Manual entry.** Always works, and nobody enjoys it. It is the fallback, not the default.

```tsx theme={null}
{installation.universalLinkUrl && (
  <Button as="a" href={installation.universalLinkUrl}>Install on this device</Button>
)}
{installation.qrCodePayload && <QrCode value={installation.qrCodePayload} />}
<ManualDetails {...installation.manual} />
```

## The QR problem

**A phone cannot scan a QR code displayed on its own screen.**

This catches nearly every integration once. Someone opens your app on the phone that will use the eSIM, sees a QR, and has nothing to scan it with.

Handle it explicitly:

* Lead with the universal link when the customer is *on* the target device.
* Say so beside the QR: *"Scan this from the device that will use the eSIM."*
* Make the manual details copyable, because they are what someone falls back to.
* Offer to email or message the QR, so it can be opened on a laptop and scanned from the phone.

<Note>
  Sending the install details by email is a legitimate flow, not a workaround. A traveller printing a QR before a flight is doing the sensible thing.
</Note>

## Treat the code as a credential

Whoever holds the activation code can install the eSIM. There is no second factor, and the profile can only be installed once.

* **Do not log it.** Not in request logs, not in error reports, not in analytics.
* **Do not show it to staff.** The Sakawave admin API deliberately does not return it, for exactly this reason — a support tool that can hand out activation codes can be talked into handing out activation codes.
* **Show it to the person the eSIM is for**, and nobody else.
* **It does not need to be stored by you.** Fetch it from `/installation` when it is needed.

## Device support

Nothing in this API can tell you whether a particular handset supports eSIM. Broadly:

| | Support |
| - | - |
| iPhone | XS and later, excluding the Chinese mainland models |
| Android | Most flagships since 2019 — Pixel 3+, Galaxy S20+, and others |
| Carrier locked | An eSIM will not install on a carrier-locked phone |

Ask before you sell. The most common support case is not a broken eSIM; it is a phone that was never going to take one, or one still locked to a network.

A useful check a customer can run themselves: dial `*#06#`. If an **EID** appears alongside the IMEI, the device supports eSIM.

## Reading the status back

You cannot observe the install directly, but the status tracks it closely enough.

| Status | What it tells you |
| - | - |
| `ready` | Issued. Nobody has installed it yet. |
| `in_use` | Installed and carrying data — the install worked. |
| `depleted` / `expired` | It worked, and has now run out. |

An eSIM sitting at `ready` days after purchase is the signal that someone is stuck. That is the moment to send the install details again, not after they complain.

`esim.profile.installed` fires on the transition, so you can prompt on silence rather than polling for it.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.