Skip to main content
Every MIOeSIM API request requires two security elements: a token that identifies your session, and a sign that proves the request parameters have not been tampered with. You obtain the token by calling the login endpoint; you compute the sign yourself using an HMAC-MD5 algorithm applied to the sorted request parameters and your secret key.

Obtaining a token

Call POST /api_order/login to exchange your credentials for a session token. The login request itself also requires a sign — see Computing the signature below for how to generate it.

Request parameters

phonenumber
string
required
Your MIOeSIM account phone number. This is your login username.
password
string
required
Your MIOeSIM account password.
sign
string
required
HMAC-MD5 signature computed from phonenumber and password. See Computing the signature.

Example request and response

curl --request POST \
  --url "https://bpm.mioesim.com/api_order/login" \
  --header "Content-Type: application/json" \
  --data '{
    "phonenumber": "13800000000",
    "password": "mypassword",
    "sign": "a1b2c3d4e5f6..."
  }'
{
  "code": 1,
  "message": "Successful",
  "data": {
    "token": "29281-9EFE5E410BEF5300DD15E3830BD65601"
  }
}

Computing the signature

Every API request — including the login request — requires a sign parameter. Compute it using the following algorithm:
  1. Collect all request parameters except sign itself.
  2. Format each parameter as key=value.
  3. Sort the resulting strings alphabetically.
  4. Concatenate all sorted strings with no separator.
  5. Append your secret key directly to the end of the concatenated string.
  6. MD5 hash the full string (UTF-8 encoded).
  7. Use the hex digest as the sign value.
Example — signing a login request with phonenumber=13800000000 and password=mypassword:
Step 1-2: ["phonenumber=13800000000", "password=mypassword"]
Step 3:   ["password=mypassword", "phonenumber=13800000000"]
Step 4:   "password=mypasswordphonenumber=13800000000"
Step 5:   "password=mypasswordphonenumber=138000000001234567890qwertyuiopasdfghjklzxc"
Step 6-7: MD5("password=mypasswordphonenumber=138000000001234567890qwertyuiopasdfghjklzxc")
          → <hex-digest>
Your secret key grants full access to your account. Never expose it in client-side code, public repositories, or logs.

Code examples

import java.util.*;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;

public static String createSign(Map<String, Object> map) throws Exception {
    final String sign_key = "1234567890qwertyuiopasdfghjklzxc";
    StringBuffer buffer = new StringBuffer();
    List<String> arrayList = new ArrayList<String>();
    map.remove("sign");
    for (String item : map.keySet()) {
        arrayList.add(item + "=" + map.get(item));
    }
    Collections.sort(arrayList);
    for (String string : arrayList) {
        buffer.append(string);
    }
    String content = buffer + sign_key;
    byte[] data = content.getBytes("UTF-8");
    return Hex.encodeHexString(DigestUtils.md5(data));
}

Using the token

After a successful login, include the token and sign on every subsequent request. For GET requests, pass them as query parameters. For POST requests, include them in the request body. GET example:
curl --request GET \
  "https://bpm.mioesim.com/api_esim/getSkus?token=29281-9EFE5E410BEF5300DD15E3830BD65601&sign=<computed-sign>"
POST example:
curl -X POST https://bpm.mioesim.com/api_esim/addEsimOrder \
  -d "token=29281-9EFE5E410BEF5300DD15E3830BD65601" \
  -d "skuId=26" \
  -d "priceId=441" \
  -d "count=1" \
  -d "backInfo=1" \
  -d "sign=<computed-sign>"
Compute the sign fresh for each request, using all parameters in that specific request (excluding sign itself).

Token expiry

Tokens are valid for 2 hours from the time of issue. After a token expires, all requests return an authentication error. To handle expiry gracefully:
  • Store the token and its issue timestamp locally.
  • Before each request, check whether the token is within 10–15 minutes of its 2-hour expiry.
  • If it is, call POST /api_order/login to obtain a fresh token before proceeding.
Avoid calling the login endpoint on every request — fetch a new token only when necessary.

Error codes

The login endpoint returns the following error codes in the code field of the response:
CodeMeaning
1Success — token returned in data
-1Wrong username or password
-2Username or password is empty
-3Account does not have call permission
-30Signature (sign) is incorrect
If you receive -30, verify that your signature algorithm sorts parameters alphabetically and that you are using the correct secret key.