API v2 Documentation

All v2 endpoints use Bearer token authentication and return a standard response envelope.

Header required in all requests:

Authorization: Bearer <your_token>

Standard Response Envelope

All v2 endpoints wrap responses in a consistent envelope:

// Success (2xx)
{
  "data": { },
  "meta": { "requestId": "..." },
  "message": "Additional message" // Optional
}

// Error (4xx / 5xx)
{
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable description",
    "details": { }
  },
  "meta": { "requestId": "..." }
}

User

User profile, permissions and wallet endpoints. Prefix: /api/v2/user

GET /api/v2/user/permissions

Returns the list of permissions assigned to the authenticated user.

Response:

{
  "data": {
    "permissions": ["acceso_srcm", "acceso_msmvl"]
  },
  "meta": { "requestId": "..." }
}
GET /api/v2/user/wallet

Returns wallet information (balance, currency) for the authenticated user.

Response:

{
  "data": {
    "balance": 50000,
    "currency": "EUR"
  },
  "meta": { "requestId": "..." }
}

Possible errors:

Code HTTP Description
UNAUTHORIZED 401 Missing or invalid authentication token
WALLET_NOT_FOUND 404 No wallet associated to the authenticated user
GET /api/v2/user/wallet/history

Returns the wallet balance change history for the authenticated user.

Query params:

Name Type Description
limit number Items per page (default: 10)
offset number Offset for pagination, max 100 (default: 0)

Response:

{
  "data": [
    {
      "name": "John Doe",
      "amount": 1500,
      "type": "debit",
      "description": "eSIM activation",
      "createdAt": "2026-03-11T10:00:00.000Z"
    }
  ],
  "meta": { "requestId": "..." }
}

Possible errors:

Code HTTP Description
UNAUTHORIZED 401 Missing or invalid authentication token
INVALID_QUERY 400 Invalid limit or offset query parameters
WALLET_NOT_FOUND 404 No wallet associated to the authenticated user
internal_error 500 Failed to retrieve wallet history

MSMVL - Activation

SIM/eSIM activation via MSMVL. Prefix: /api/v2/msmvl/activation. Requires acceso_msmvl permission.

Compatibility note: for compatibility, the brand value "Lyca" also covers Llamaya. The API parameter must still be sent as "Lyca".

POST /api/v2/msmvl/activation

Registers and activates a SIM or eSIM number. Performs ICC validation (SIM only), document/age validation, and the activation call. Checks wallet balance before activation, but does not charge the wallet nor trigger recharge or bundle in this step.

After a successful activation, follow the corresponding flow depending on the SIM type:

SIM type Required steps (in order)
eSIM /bundlecash
Physical SIM — product price > facial value /recharge/bundle
Physical SIM — product price ≤ facial value /bundlecash

Orange brand is not available for this endpoint and will return BRAND_NOT_AVAILABLE.

Body (JSON):

{
  "productId": "PO_Mali_M",
  "brand": "Lebara",
  "name": "Juan",
  "surname": "Pérez",
  "surname2": "García",
  "documentNumber": "12345678A",
  "dateOfBirth": "1990-05-15",
  "nationalityId": "ES",
  "iccId": "89340712341234567890",
  "simType": "sim",
  "identificationType": "personal-identity-code",
  "email": "user@example.com",
  "language": "eng"
}

Body fields:

Field Type Description
productId string Product/plan identifier (required)
brand "Lebara" | "Lyca" | "Orange" Brand (required). Use "Lyca" when referring to Llamaya.
name string Customer first name (required)
surname string Customer first surname (required)
surname2 string Customer second surname (optional)
documentNumber string Document number (required)
dateOfBirth string Date of birth (required)
nationalityId string Nationality code, 2 chars ISO (required)
iccId string ICC ID, 19–20 chars (required when simType is sim)
simType "sim" | "esim" SIM type (required)
identificationType "business-identity-code" | "nie" | "passport" | "personal-identity-code" Document type (required)
email string Customer email (required)
language string Contact language, 3 chars ISO 639-2/T (required, e.g. "eng")

Success response:

{
  "data": {
    "msisdnId": "612345678",
    "qrCode": "LPA:1$sm-..."
  },
  "message": "Activation completed successfully.",
  "meta": { "requestId": "..." }
}

Success data fields:

Field Type Description
msisdnId string Assigned phone number
qrCode string | null QR code for eSIM activation (null for physical SIM)

⏱️ The generated QR code (qrCode) is valid for 24 hours from the moment of activation. After that period, the QR expires and cannot be used to install the eSIM.


Possible errors:

Code HTTP Description
BRAND_NOT_AVAILABLE 400 Orange brand is not available for this endpoint
WALLET_NOT_FOUND 500 No wallet associated to user
PRODUCT_NOT_FOUND 400 Requested product not found
ICC_ID_REQUIRED 400 iccId missing when simType is "sim"
ACTIVATION_COST_UNAVAILABLE 400 Could not determine the activation cost for the SIM
ICC_ID_NOT_AVAILABLE 400 The provided ICC ID is not available for activation
INSUFFICIENT_BALANCE 400 Wallet balance too low — retry after topping up the wallet
ACTIVATION_SAVE_FAILED 500 SIM activated but DB record failed — contact support with the msisdnId in error.details
POST /api/v2/msmvl/activation/recharge

Step 2 — Charge the user's wallet and trigger the external recharge for the number. Call this after a successful POST /activation.

For physical SIM: charges only the difference between the product price and the SIM facial value. If the facial value already covers the full product price, the wallet is not charged and the operation succeeds immediately. In that case, you may also skip this endpoint entirely and call /bundlecash directly instead of invoking /recharge + /bundle separately.

Body (JSON):

{
  "mobileNumber": "612345678"
}

Body fields:

Field Type Description
mobileNumber string Mobile number from the activation step (required)

Success response:

{
  "data": {
    "msisdnId": "612345678",
    "valueCharged": 5.00
  },
  "message": "Recharge completed successfully. 5 EUR have been deducted from the wallet.",
  "meta": { "requestId": "..." }
}

Possible errors:

Code HTTP Description
ACTIVATION_NOT_FOUND 404 No activation registered for this mobile number
FORBIDDEN 403 The activation belongs to a different user
ACTIVATION_PRODUCT_MISSING 500 Activation has no product associated
PRODUCT_NOT_FOUND 400 Requested product not found
ICC_ID_MISSING 500 Physical SIM activation has no ICCID associated
ACTIVATION_COST_UNAVAILABLE 400 Could not determine the recharge cost for this SIM
WALLET_NOT_FOUND 500 No wallet associated to user
INSUFFICIENT_BALANCE 400 Wallet balance too low — retry after topping up the wallet
WALLET_UPDATE_FAILED 500 Failed to deduct from wallet
BRAND_NOT_MAPPED 400 Brand could not be mapped to the configured recharge product
RECHARGE_FAILED 500 External recharge call failed
POST /api/v2/msmvl/activation/bundle

Step 3a (physical SIM) — Purchases the bundle to apply the product tariff to the number.

Body (JSON):

{
  "mobileNumber": "612345678"
}

Body fields:

Field Type Description
mobileNumber string Mobile number from the activation step (required)

Success response:

{
  "data": {
    "msisdnId": "612345678",
    "provisionId": "PROV-123456"
  },
  "message": "Bundle purchased successfully.",
  "meta": { "requestId": "..." }
}

Possible errors:

Code HTTP Description
ACTIVATION_NOT_FOUND 404 No activation registered for this mobile number
FORBIDDEN 403 The activation belongs to a different user
ACTIVATION_PRODUCT_MISSING 500 Activation has no product associated
PRODUCT_NOT_FOUND 400 Requested product not found
BUNDLE_FAILED 500 Bundle purchase failed — contact support
POST /api/v2/msmvl/activation/bundlecash

Combines the recharge (/recharge) and bundle purchase (/bundle) into a single call. Can be used in two scenarios:

  • eSIM activations — shortcut that replaces both /recharge and /bundle.
  • Physical SIM activations where the product price ≤ facial value — since no recharge is needed, you can skip /recharge and /bundle and call this endpoint directly to apply the bundle in one step.

Body (JSON):

{
  "mobileNumber": "612345678"
}

Body fields:

Field Type Description
mobileNumber string Mobile number from the activation step (required)

Success response:

{
  "data": {
    "msisdnId": "612345678",
    "basketReference": "REF-123",
    "basketId": "BKT-456",
    "localReference": "LOC-789"
  },
  "message": "BundleCash applied successfully.",
  "meta": { "requestId": "..." }
}

Possible errors:

Code HTTP Description
ACTIVATION_NOT_FOUND 404 No activation registered for this mobile number
FORBIDDEN 403 The activation belongs to a different user
BUNDLECASH_REQUIRES_ESIM 400 BundleCash is only valid for eSIM activations or physical SIM activations where the product price ≤ facial value
ACTIVATION_PRODUCT_MISSING 500 Activation has no product associated
PRODUCT_NOT_FOUND 400 Requested product not found
BUNDLECASH_FAILED 500 BundleCash application failed — contact support
POST /api/v2/msmvl/activation/deactivation-roaming

Step 4 — Deactivates roaming control for the activated number. Call this after bundle/bundlecash succeeds. For Lyca Globe products, the operation is skipped automatically and success is returned.

Body (JSON):

{
  "mobileNumber": "612345678"
}

Body fields:

Field Type Description
mobileNumber string Mobile number from the activation step (required)

Success response:

{
  "data": { "msisdnId": "612345678" },
  "message": "Roaming deactivated successfully.",
  "meta": { "requestId": "..." }
}

Possible errors:

Code HTTP Description
ACTIVATION_NOT_FOUND 404 No activation registered for this mobile number
FORBIDDEN 403 The activation belongs to a different user
GET /api/v2/msmvl/activation/facial/:iccId

Get the facial value (activation cost) for a given ICC ID. Used to determine how much balance the SIM already has before activation.

Path params:

Name Type Description
iccId string ICC ID, 19–20 chars (required)

Query params:

Name Type Description
brand "Lebara" | "Lyca" | "Orange" Brand name (required)
language string Language code, 2 chars ISO 639-1 (required)

Response:

{
  "data": {
    "value": 10.00
  },
  "meta": { "requestId": "..." }
}
GET /api/v2/msmvl/activation/history

Get MSMVL activation history for the authenticated user.

Query params:

Name Type Description
page number Page number, min 1 (default: 1)
limit number Items per page, 1–100 (default: 10)
dateFrom date Filter from date (optional, ISO format)
dateTo date Filter to date (optional, ISO format)

Response:

{
  "data": {
    "activationHistory": [
      {
        "id": 1,
        "msisdnId": "612345678",
        "qrCode": "LPA:1$sm-...",
        "createdAt": "2026-03-11T10:00:00.000Z"
      }
    ],
    "total": 42
  },
  "message": "Activation history retrieved successfully.",
  "meta": { "requestId": "..." }
}

MSMVL – Validation

Validation utilities. Prefix: /api/v2/msmvl/validate. Requires acceso_msmvl permission.

GET /api/v2/msmvl/validate/:iccid

Validate if an ICC ID (SIM card identifier) is available for activation.

Query params:

Name Type Description
brand "Lebara" | "Lyca" | "Orange" Brand (required)
GET /api/v2/msmvl/validate/age

Validate minimum age requirement (must be at least 18 years old).

Query params:

Name Type Description
dateOfBirth string Date of birth in YYYY-MM-DD format (required)
GET /api/v2/msmvl/validate/document

Validate an identification document number.

Query params:

Name Type Description
documentNumber string Document number (required)
identificationType "business-identity-code" | "nie" | "passport" | "personal-identity-code" Document type (required)

MSMVL – Products

Product catalog. Prefix: /api/v2/msmvl/products. Requires acceso_msmvl permission.

GET /api/v2/msmvl/products

Get the list of available products for a brand.

Query params:

Name Type Description
brand "Lebara" | "Lyca" | "Orange" Brand (required). Use "Lyca" when referring to Llamaya.
language "en" | "es" Language for product names (optional. 'es' by default)

MSMVL – MSISDN Operations

Phone number management. Prefix: /api/v2/msmvl/msisdn-op. Requires acceso_msmvl permission.

GET /api/v2/msmvl/msisdn-op/operator/:msisdn

Get the operator info for a phone number (current operator, origin, portability status).

GET /api/v2/msmvl/msisdn-op/balance/:msisdn

Get balance for a phone number.

Query params:

Name Type Description
brand "Lebara" | "Lyca" | "Orange" Brand (required)
GET /api/v2/msmvl/msisdn-op/msisdn/:msisdn

Get comprehensive MSISDN info (ICC ID, IMSI, PINs, PUKs, status, product, balance, bonuses, QR code).

Query params:

Name Type Description
brand "Lebara" | "Lyca" | "Orange" Brand (required)
GET /api/v2/msmvl/msisdn-op/msisdn/:mobileNumber/services

Get active services for a phone number.

Query params:

Name Type Description
brand "Lebara" | "Lyca" | "Orange" Brand (required)
GET /api/v2/msmvl/msisdn-op/msisdn/:mobileNumber/esimQr

Get eSIM activation QR info (URL and request date) for a phone number.

Query params:

Name Type Description
brand "Lebara" | "Lyca" | "Orange" Brand (required)

MSMVL – Inventory

Inventory lookup. Prefix: /api/v2/msmvl/inventory. Requires acceso_msmvl permission.

GET /api/v2/msmvl/inventory/:mobileNumber

Get inventory info (ID and brand) for a mobile number.

Path params:

Name Type Description
mobileNumber string Mobile number, exactly 9 digits (required)

Response:

{
  "data": {
    "id": "INV_12345",
    "brand": "Lebara"
  },
  "meta": { "requestId": "..." }
}