---
title: "Import a BYO (tenant-supplied) physical eSIM activation code"
method: POST
path: "/numbers/esims/import"
tags: ["Esims"]
---

# Import a BYO (tenant-supplied) physical eSIM activation code

`POST /numbers/esims/import`

Registers a bring-your-own (BYO) eSIM activation code as owned inventory. Provide either `{ smdpAddress, matchingId?, confirmationCode? }` or `{ lpaCode }` — supplying both, or neither, returns 400. An optional `name` sets a display label on the created eSIM (up to 15 characters).

Subject to per-owner and daily import limits, and disabled entirely unless BYO imports are enabled for this deployment (409 `byo_disabled`). Idempotent via `idempotencyKey`: replaying the same key with an identical request returns the original response; the same key with a different request returns 409 `idempotency_conflict`.

When rent-first billing is off (default), the import is free — 201 with the eSIM. Setting `autoInstall: true` additionally dispatches an install immediately after import (`deviceId` may only be set together with `autoInstall`): this returns 202 with `{esim, operationId, statusUrl}` when the install claim succeeds (poll `GET /esims/{id}/install-status`), or 201 with the eSIM plus `installDispatch: {ok: false, reason}` when the install could not be dispatched — the import itself still succeeds either way.

When rent-first billing is on, import additionally requires available device capacity (409 `device_pool_empty`) and is subject to a per-owner awaiting-payment cap (409 `byo_awaiting_payment_cap`). On success the eSIM is created `awaiting_payment` and a checkout is started: 201 with `{esim, rentStatus, checkoutUrl}` when the checkout URL is ready immediately, or 202 with `checkoutUrl: null` otherwise — poll `GET /esims/{id}` until it's populated. Once payment is confirmed, install is triggered automatically.

## Request body

- ImportEsimInput
  - `smdpAddress` string — SM-DP+ activation host — bare hostname ONLY, no port/scheme/path.
  - `matchingId` string
  - `confirmationCode` string
  - `lpaCode` string — Full LPA activation code
  - `carrierName` string
  - `countryCode` string
  - `notes` string
  - `msisdn` string — Self-reported E.164 MSISDN for this eSIM's line — an unverified label, never used for routing
  - `name` string, nullable — User-defined display label — NFC-normalized, up to 15 GRAPHEMES (not UTF-16 code units; an emoji/flag may span several). Omit/null/empty/whitespace-only leaves it unset.
  - `idempotencyKey` string — Client-supplied key; replaying the same key+request returns the original import instead of importing again
  - `autoInstall` boolean — Rent OFF only: dispatch install-on-device immediately after a successful import. No-op when ESIM_BYO_RENT_ENABLED=true.
  - `deviceId` string — physedge device id to auto-install onto; requires autoInstall:true and rent OFF. Omit for a random pool device.

## Response `201`

eSIM imported — plain eSIM, an inline-resolved rent checkout, or an eSIM with a failed autoInstall dispatch

- object
  - `data` union, required
    - PublicEsim
      - `id` string, uuid, required
      - `status` 'in_stock' | 'owned' | 'installing' | 'installed' | 'install_failed' | 'retired', required
      - `source` 'stocked' | 'byo', required
      - `carrierName` string, nullable, required
      - `countryCode` string, nullable, required
      - `iccid` string, nullable, required
      - `subscriptionId` integer, nullable, required
      - `deviceId` string, uuid, nullable, required
      - `deviceUuid` string, nullable, required
      - `msisdn` string, nullable, required
      - `name` string, nullable, required
      - `createdBy` string, nullable, required
      - `networkStatus` 'degraded' | 'null', nullable, required
      - `rentStatus` 'not_applicable' | 'exempt' | 'inactive' | 'awaiting_payment' | 'active' | 'cancel_pending' | 'refund_pending' | 'retiring' | 'billing_error'
      - `checkoutUrl` string, nullable
      - `currentPeriodEnd` string, date-time, nullable
      - `cancellationScheduled` boolean
      - `exempt` boolean
      - `createdAt` string, date-time, nullable, required
      - `updatedAt` string, date-time, nullable, required
    - EsimAwaitingPaymentResponse
      - `esim` PublicEsim, required
        - `id` string, uuid, required
        - `status` 'in_stock' | 'owned' | 'installing' | 'installed' | 'install_failed' | 'retired', required
        - `source` 'stocked' | 'byo', required
        - `carrierName` string, nullable, required
        - `countryCode` string, nullable, required
        - `iccid` string, nullable, required
        - `subscriptionId` integer, nullable, required
        - `deviceId` string, uuid, nullable, required
        - `deviceUuid` string, nullable, required
        - `msisdn` string, nullable, required
        - `name` string, nullable, required
        - `createdBy` string, nullable, required
        - `networkStatus` 'degraded' | 'null', nullable, required
        - `rentStatus` 'not_applicable' | 'exempt' | 'inactive' | 'awaiting_payment' | 'active' | 'cancel_pending' | 'refund_pending' | 'retiring' | 'billing_error'
        - `checkoutUrl` string, nullable
        - `currentPeriodEnd` string, date-time, nullable
        - `cancellationScheduled` boolean
        - `exempt` boolean
        - `createdAt` string, date-time, nullable, required
        - `updatedAt` string, date-time, nullable, required
      - `rentStatus` 'awaiting_payment', required
      - `checkoutUrl` string, nullable, required
    - EsimImportInstallDispatchFailedResponse
      - `id` string, uuid, required
      - `status` 'in_stock' | 'owned' | 'installing' | 'installed' | 'install_failed' | 'retired', required
      - `source` 'stocked' | 'byo', required
      - `carrierName` string, nullable, required
      - `countryCode` string, nullable, required
      - `iccid` string, nullable, required
      - `subscriptionId` integer, nullable, required
      - `deviceId` string, uuid, nullable, required
      - `deviceUuid` string, nullable, required
      - `msisdn` string, nullable, required
      - `name` string, nullable, required
      - `createdBy` string, nullable, required
      - `networkStatus` 'degraded' | 'null', nullable, required
      - `rentStatus` 'not_applicable' | 'exempt' | 'inactive' | 'awaiting_payment' | 'active' | 'cancel_pending' | 'refund_pending' | 'retiring' | 'billing_error'
      - `checkoutUrl` string, nullable
      - `currentPeriodEnd` string, date-time, nullable
      - `cancellationScheduled` boolean
      - `exempt` boolean
      - `createdAt` string, date-time, nullable, required
      - `updatedAt` string, date-time, nullable, required
      - `installDispatch` object, required
        - `ok` false, required
        - `reason` string, required

## Other responses

- `202` — Import accepted but not yet resolved. With rent-first billing on, the checkout URL isn't ready yet — poll `GET /esims/{id}` (no `Retry-After`). With `autoInstall: true`, the install was dispatched — poll `GET /esims/{id}/install-status` (`Retry-After: 5`). Distinguish by shape: `rentStatus`+`checkoutUrl` (rent checkout) vs. `operationId`+`statusUrl` (install pending).
- `400` — Bad Request
- `401` — Unauthorized
- `409` — Conflict — see `reason` for the stable, machine-readable cause
- `500` — Internal Server Error
- `503` — Service Unavailable — esims are disabled for this deployment (see `reason`)

---

[API](https://skmtc.dev/droidrun/apis/droidrun-cloud.md) · [All operations](https://skmtc.dev/droidrun/apis/droidrun-cloud/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/droidrun/droidrun-cloud/revisions/a1453ac769d4/schema)
